年齢の計算

2010.06.08 Author: Jas

さまざまなシステムで頻出する生年月日から年齢の計算。
計算が苦手な私にとっては結果があっているかの判断が難しく、特に閏年関連は厄介です。

今回も年齢計算が必要な機能があったので、閏年が正しく処理できるかテストしてみました。

[目標]
・1980/02/29(閏日)生まれの人の年齢計算が正しく行えること
・もちろん、閏日以外の人も。。。

[想定結果]
・閏年の場合は、2/29に年齢が増える
・閏年以外は、3/1に年齢が増える

1. PostgreSQLの場合
PostgreSQLには、age()という便利な関数があるのでどんな結果になるか試してみました。

SELECT
 EXTRACT(YEAR FROM AGE('2010/02/28', '1980/02/29')),
 EXTRACT(YEAR FROM AGE('2010/03/01', '1980/02/29')),
 EXTRACT(YEAR FROM AGE('2008/02/29', '1980/02/29'))

結果は、
-----------
29 | 30 | 28
-----------

バッチリです。
想定通りの結果になりました。


2. Oracleの場合
Oracleには、MONTHS_BETWEEN()という月の差を求める関数があるので使えるかどうかテスト!

SELECT
 TRUNC(MONTHS_BETWEEN(TO_DATE('2010/02/28', 'yyyy/mm/dd'), TO_DATE('1980/02/29', 'yyyy/mm/dd')) / 12),
 TRUNC(MONTHS_BETWEEN(TO_DATE('2010/03/01', 'yyyy/mm/dd'), TO_DATE('1980/02/29', 'yyyy/mm/dd')) / 12),
 TRUNC(MONTHS_BETWEEN(TO_DATE('2008/02/29', 'yyyy/mm/dd'), TO_DATE('1980/02/29', 'yyyy/mm/dd')) / 12)
FROM DUAL

結果は、
-----------
30 | 30 | 28
-----------

この方法だと、閏年ではない年の場合、2/28に年齢が加算されてしまうようです。
3/1に年齢が増える想定だったので、この結果はNG
残念。


結局、Oracleで想定通りの結果をだすには、以下のような式になります。

SELECT
 TRUNC((20100228 - 19800229) / 10000, 0)
FROM DUAL

要するに、(([基準日] - [生年月日]) / 10000) の結果を整数で切り捨てです。
この計算方法であれば、Oracleに限らず、他のデータベースやプログラムでも同じ計算結果になるようです。

次回から年齢の計算で困らないように覚え書きでした。。。

名古屋のWebシステム開発・ネットワーク構築会社 コネクティボへ