年齢を計算する(暦年齢)
満年齢
一般的な年齢
生まれた年は 0歳 として翌年の誕生日に年齢 +1 する。
民法など特定の状況で使用される年齢
生まれた年は 0歳 として翌年の誕生日の前日に年齢 +1 する。
入学資格や一部の法令には月末における年齢を条件にしていることが多い。1日生まれの人は前の月末には
年齢が加算されていることになっているので 1日生まれの人は行政サービス(就学、年金や所得税など)を受けるときには要注意。(「但し書き」もされているらしい)
数え年
生まれた年は 1歳 として翌年からは 1月1日を誕生日とする。
つまり 数え年 = 計算したい年 - 誕生した年 + 1 。
儀礼などには数え年が使われているようである。
七五三や還暦(数え年で 61歳)や喜寿(数え年で 77歳)、厄除け、厄払いなどに使われる。
YEARS_OF_AGE ファンクション (誕生日から年齢を算出)
デフォルトではシステム日付における年齢を算出する。
この関数での年齢の数え方について
年齢は誕生日の前日の満了をもって1歳加算される(※)、その年の誕生日に該当する日が無い場合は、その月の月末をもって満了日とする(例:2/29 生まれ)。
(※) 誕生日の当日の 0 時ではなく、前日が満了した瞬間(前日に含まれる)に+1されるとして扱っている。年齢に関する法律には時間に関する厳密な規定はないらしいですが、法律上では前日には年齢が増えているということになります。これは入学資格などにも関係している内容です。
-- うるう日生まれに対応
-- 年齢計算に関する法律を考慮した場合において、BASEDATE が大晦日のときの問題に対応
-- P_METHOD: 0:一般的な年齢/1:年齢計算に関する法律を考慮/2:数え年
CREATE OR REPLACE FUNCTION RIVUS.YEARS_OF_AGE(
P_BIRTHDAY IN DATE,
P_BASEDATE IN DATE := SYSDATE,
P_METHOD IN NUMBER := 0 )
RETURN NATURAL
IS
vBaseDate DATE := P_BASEDATE;
vYearsOffset PLS_INTEGER := 0;
vYears PLS_INTEGER;
BEGIN
IF (P_METHOD = 1) THEN
vBaseDate := vBaseDate + 1;
END IF;
vYears := EXTRACT(YEAR FROM vBaseDate) - EXTRACT(YEAR FROM P_BIRTHDAY);
IF (P_METHOD = 2) THEN
vYearsOffset := 1;
ELSIF (TO_CHAR(vBaseDate, 'MMDD') < TO_CHAR(P_BIRTHDAY, 'MMDD')) THEN
vYearsOffset := -1;
END IF;
RETURN vYears + vYearsOffset;
END;
/
-- 一般的な年齢についての SQL 変換例
-- 少々長くなるが以下のようになる
SELECT
EXTRACT(YEAR FROM P_BASEDATE) - EXTRACT(YEAR FROM P_BIRTHDAY) -
CASE WHEN TO_CHAR(P_BASEDATE, 'MMDD') < TO_CHAR( P_BIRTHDAY, 'MMDD') THEN
1 ELSE 0 END
FROM DUAL ;
(注意) Oracle 8i 以前の場合、EXTRACT は TO_CHAR(date_value, 'YYYY') と代替しない。カレンダ (NLS_CALENDAR) によっては年号表記の場合があるので
TO_CHAR(date_value, 'YYYY', 'NLS_CALENDAR=''GREGORIAN''')
を使用するほうが安全。
CASE は DECODE(SIGN(val1-val2, 〜) 形式に変換する。
- Special Thanks : Kenji さん
MONTHS_BETWEEN(P_BASEDATE,P_BIRTHDAY)/12 では 2/29 生まれの年齢が合わない。
期間の数え方
起算日を明記していない場合には翌日から起算する。但し 起算する時間が 0時(※)の場合には当日から起算。法律上での年齢の数え方と期間の数え方では 1日異なっている。
(※) おそらく 0時00分01秒などは切り上げされてしまって翌日扱いになるのだろうと思われる。
年齢計算に関連するリンク