年齢を求める
|
60 |
GetAge |
動作確認 |
Delphi2007 |
更新日 |
2008/01/31(木) 2010/07/06(火) |
任意の日付間の年齢を調べる関数です。
ネット上には誤動作するコードが多すぎですので
チェックコードを書いておきました。
これで関数の信頼性が保たれます。
閏年の2月29日、つまり閏日に生まれた人の年齢計算については
テストコードを読むことで仕様がわかるようになっています。
閏年の誕生日は特殊な仕様が考えられるので、
閏日判定での特殊な年齢計算を行いたい場合は
GetAgeOld 関数を修正するほうがやりやすいと思います。
────────────────────
{-------------------------------
//年齢を調べる関数機能
GetAgeOld/GetAge
機能: 指定した日付の時の年齢を求めます。
今日を指定する場合CheckDateにDateを代入してください
戻り値: 年齢
備考: CheckDateがBirthDateの前の日でも
年齢が負の値になって正しい日付計算処理をします
(必要ない処理かも…)
計算するときに2通りの求め方をしてみました。
GetAgeOldはEncodeDateしているので遅いかもしれない
GetAgeを使ってください。
履歴: 2001/08/21
2008/01/30
関数名・変数名やコメントなどを修正
テストコードをしっかり記述
//------------------------------}
function GetAgeOld(BirthDate, CheckDate: TDateTime): Integer;
var
BirthYear, BirthMonth, BirthDay,
CheckYear, CheckMonth, CheckDay: Word;
begin
//誕生日,任意の日を年月日単位にバラす
DecodeDate(BirthDate, BirthYear, BirthMonth, BirthDay);
DecodeDate(CheckDate, CheckYear, CheckMonth, CheckDay);
//現在(任意の年月日)の「年」から誕生日の「年」を引く
Result := CheckYear - BirthYear;
//チェックしたい年がうるう年ではない場合
if not IsLeapYear(CheckYear) then
begin
//誕生日がうるう日なら
if (BirthMonth=2) and (BirthDay=29) then
begin
BirthMonth := 3; BirthDay := 1;
end; //誕生日を3/1にしておく
end;
//その年の誕生日を過ぎていなければさらに1歳引く
if ( EncodeDate(CheckYear, CheckMonth, CheckDay)
< EncodeDate(CheckYear, BirthMonth, BirthDay) ) then
Result := Result - 1;
End;
function GetAge(BirthDate, CheckDate: TDateTime): Integer;
var
BirthYear, BirthMonth, BirthDay,
CheckYear, CheckMonth, CheckDay: Word;
begin
DecodeDate(BirthDate, BirthYear, BirthMonth, BirthDay);
DecodeDate(CheckDate, CheckYear, CheckMonth, CheckDay);
Result := CheckYear - BirthYear;
//誕生日を過ぎていなければさらに1歳引く
if (CheckMonth < BirthMonth) then
begin
Dec(Result);
end else
if (CheckMonth = BirthMonth) then
begin
if (CheckDay < BirthDay) then
Dec(Result);
end;
End;
function Age(BirthDay, CheckDay:TDateTime):Integer;
begin
Result := GetAge(BirthDay, CheckDay);
end;
type
TAgeFunction = Function(A, B: TDateTime): Integer;
procedure testAge;
function AgeText(BirthDateText, CheckDateText: String; Func: TAgeFunction): Integer;
begin
Result :=
Func(StrToDate(BirthDateText), StrToDate(CheckDateText)) ;
end;
procedure CheckAgeFunction(BirthDateText, CheckDateText: String; CheckAge: Integer);
begin
Check(AgeText(BirthDateText, CheckDateText, GetAge), CheckAge);
Check(AgeText(BirthDateText, CheckDateText, GetAgeOld), CheckAge);
end;
begin
//閏年が誕生日 と 閏年じゃない年 との年齢
CheckAgeFunction('1992/02/28', '1993/02/27', 0);
CheckAgeFunction('1992/02/28', '1993/02/28', 1);
CheckAgeFunction('1992/02/28', '1993/03/01', 1);
CheckAgeFunction('1992/02/29', '1993/02/27', 0);
CheckAgeFunction('1992/02/29', '1993/02/28', 0);
CheckAgeFunction('1992/02/29', '1993/03/01', 1);
CheckAgeFunction('1992/03/01', '1993/02/27', 0);
CheckAgeFunction('1992/03/01', '1993/02/28', 0);
CheckAgeFunction('1992/03/01', '1993/03/01', 1);
//閏年が誕生日 と 閏年 との年齢
CheckAgeFunction('1992/02/28', '2008/02/27', 15);
CheckAgeFunction('1992/02/28', '2008/02/28', 16);
CheckAgeFunction('1992/02/28', '2008/02/29', 16);
CheckAgeFunction('1992/02/28', '2008/03/01', 16);
CheckAgeFunction('1992/02/29', '2008/02/27', 15);
CheckAgeFunction('1992/02/29', '2008/02/28', 15);
CheckAgeFunction('1992/02/29', '2008/02/29', 16);
CheckAgeFunction('1992/02/29', '2008/03/01', 16);
CheckAgeFunction('1992/03/01', '2008/02/27', 15);
CheckAgeFunction('1992/03/01', '2008/02/28', 15);
CheckAgeFunction('1992/03/01', '2008/02/29', 15);
CheckAgeFunction('1992/03/01', '2008/03/01', 16);
//閏年じゃない年が誕生日 と 閏年じゃない年 との年齢
CheckAgeFunction('1993/02/28', '1994/02/27', 0);
CheckAgeFunction('1993/02/28', '1994/02/28', 1);
CheckAgeFunction('1993/02/28', '1994/03/01', 1);
CheckAgeFunction('1993/03/01', '1994/02/27', 0);
CheckAgeFunction('1993/03/01', '1994/02/28', 0);
CheckAgeFunction('1993/03/01', '1994/03/01', 1);
//閏年じゃない年が誕生日 と 閏年 との年齢
CheckAgeFunction('2007/02/28', '2008/02/27', 0);
CheckAgeFunction('2007/02/28', '2008/02/28', 1);
CheckAgeFunction('2007/02/28', '2008/02/29', 1);
CheckAgeFunction('2007/02/28', '2008/03/01', 1);
CheckAgeFunction('2007/03/01', '2008/02/27', 0);
CheckAgeFunction('2007/03/01', '2008/02/28', 0);
CheckAgeFunction('2007/03/01', '2008/02/29', 0);
CheckAgeFunction('2007/03/01', '2008/03/01', 1);
end;
//------------------------------
────────────────────
参考────────────────────
[Delphi-ML:33755] [Delphi-ML:33757] Re: 生年月日から年齢を取得
http://www2.big.or.jp/~osamu/Delphi/browse.cgi?index=33755
CheckAgeFunction('1992/02/29', '1993/02/27', 0);
このテストを通過しません。
http://www2.big.or.jp/~osamu/Delphi/browse.cgi?index=33757
CheckAgeFunction('1992/03/01', '1993/02/27', 0);
このテストを通過しません。
Delphi/年齢計算 - LANDHERE Wiki
http://wiki.landhere.info/pukiwiki.php?Delphi%2F%E5%B9%B4%E9%BD%A2%E8%A8%88%E7%AE%97
ソースも間違っているし(2つめのDecodeDate)
CheckAgeFunction('1992/02/28', '1993/03/01', 1);
このテストを通過しません。
smdn: Delphiで遊んでみる その2.言語仕様中編
http://smdn.invisiblefulmoon.net/ikimasshoy/delphi/learningdelphi2.html
CalcAge
全テスト通過。上記のGetAgeと実装は同じです。
年齢を計算するには?
http://homepage1.nifty.com/MADIA/delphi/delphi_bbs/200702/200702_07020046.html
DelFusaBlog 年齢計算
http://delfusa.blog65.fc2.com/blog-entry-42.html
関数名や変数名を変えただけで同一。
2/29生まれの人の誕生日について
きょうは何の日〜毎日が記念日〜
http://www.nnh.to/02/29.html
Yomiuri On-Line / なんでもクエスチョン
「早生まれ」4月1日含むのはなぜ?
http://www.yomiuri.co.jp/nandemo/list/20010129.htm
AddinBox期間計算まとめ
http://www.h3.dion.ne.jp/~sakatsu/period_topic2.htm
|