年齢の計算
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システム開発・ネットワーク構築会社 コネクティボへ