記事の最後に載せたプログラムのコメントにも書きましたが、ポイントは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 件のコメント:
コメントを投稿