記事の最後に載せたプログラムのコメントにも書きましたが、ポイントは2つあります。
- 基準日の年と生年の差
- 基準日がその年の誕生日よりも前のときは1を減算する
2015/8/31
NARITA Shoさんから「Excel 界隈では「基準日」という語が使われているみたいですね。」とのコメントを頂きました。ありがとうございました。
以下、xyzzy lispとC#での実装を記載します。
2015/9/2
C#での実装例を追加しました。
(defun compute-age (birth-date &optional date)
"生年月日(universal-time)から年齢を計算する関数
dateが指定されない時は現時点の年齢を計算する"
;; 年月日のみ計算に使用する
;; 基本的には対象年と生年月日の年を返す。
;; ただし、対象年の誕生日を迎えていない時は1を減算して返す。
(setq date (if (null date) (get-universal-time) date))
(multiple-value-bind
(_ _ _ birth-day birth-month birth-year)
(decode-universal-time birth-date)
(multiple-value-bind
(_ _ _ day month year)
(decode-universal-time date)
(if (> (encode-universal-time 0 0 0 birth-day birth-month year)
(encode-universal-time 0 0 0 day month year))
(1- (- year birth-year))
(- year birth-year)))))
using System;
namespace Seekones.Util
{
/// <summary>
/// 誕生日クラス
/// </summary>
public class Birthday
{
/// <summary>生年月日</summary>
private readonly DateTime birthday;
/// <summary>
/// 生年月日を指定してインスタンス化する
/// </summary>
public Birthday(DateTime birthday)
{
this.birthday = birthday;
}
/// <summary>
/// 当日を基準日として年齢を計算する
/// </summary>
public int ComputeAge()
{
return ComputeAge(DateTime.Today);
}
/// <summary>
/// referenceDate時点での年齢を計算する
/// </summary>
public int ComputeAge(DateTime referenceDate)
{
// 基準年と生年を取得する
var referenceYear = referenceDate.Year;
var birthYear = birthday.Year;
// 基準年と生年の差を算出する
var subYear = referenceYear - birthYear;
// 基準年の誕生日を取得する
var birthdayOfReferenceYear = birthday.AddYears(subYear);
// 年齢を算出する
var age = 0;
if (birthdayOfReferenceYear > referenceDate)
{
// 基準年の誕生日を迎えていない時は、基準年と生年の差から
// 1を減算して年齢とする
age = subYear - 1;
}
else
{
// 基準年の誕生日を迎えているときは、基準年と生年の差を
// 年齢とする
age = subYear;
}
return age;
}
#if UT
/// <summary>
/// 単体テスト用メインメソッド
///
public static void Main(string[] args)
{
testComputeAge("1970/01/01", "1971/01/01", 1);
testComputeAge("1970/01/01", "1971/12/31", 1);
}
/// <summary>
/// 生年月日テストメソッド
/// </summary>
/// <param name="strBirthday" />生年月日(yyyy/MM/dd)
/// <param name="strReferenceDate" />基準日(yyyy/MM/dd)
/// <param name="expectedAge" />期待する年齢
private static void testComputeAge(string strBirthday,
string strReferenceDate,
int expectedAge)
{
var birthday = DateTime.Parse(strBirthday);
var referenceDate = DateTime.Parse(strReferenceDate);
var birthdayObj = new Birthday(birthday);
var age = birthdayObj.ComputeAge(referenceDate);
if (age == expectedAge)
{
Console.WriteLine("OK");
return;
}
Console.WriteLine("NG: expected:" + expectedAge + " actual:" + age);
}
#endif
}
}
0 件のコメント:
コメントを投稿