皆もすなるQiitaといふものを、儂もしてみむとてするなり。
と言う訳で、こん**は!はなっち!です。
前回、AndAlso演算子と言うのを解説しました。これを効果的に使えるシーンってなんだろう?と考えた時、年齢を算出するxamlはどうか?と思い立って、早速作ってみました。
###年齢はどうやって計算
年齢はどうやって計算するか。まぁ普通なら算出年から生年を引いて、誕生日を迎えていなかったら-1するのが正攻法なのでしょうが、今回は生年から算出年まで繰り返してやってみようと思うのです。
さて、入力には、DateTime型の誕生日と、DateTime型の算出日。出力は年齢ですね。DateTime型の算出日が未設定であったら、Nowとするようにしました。
DateTime型は、未設定状態だと0001/01/01 00:00:00となるので、.Year()で得た年が1だったらと言う条件ですね。
あとは簡単に、生年月日の年から算出日の年までを繰り返し、その年の誕生日が生年月日より大きく、算出日以下である時に年齢を+1すればいいのですね。
コレクション:Enumerable.Range(誕生日.AddDays(1).Year, 算出日.Year - 誕生日.AddDays(1).Year + 1)
要素:Int32型
⇒誕生日の翌日の年を始値とし、算出日の年から始値を引き、+1する。
条件: 誕生日.CompareTo(New DateTime(Y, 誕生日.Month, 誕生日.Day)).Equals(-1)
AndAlso Not 算出日.CompareTo(New DateTime(Y, 誕生日.Month, 誕生日.Day)).Equals(-1)
⇒誕生日 < 計算年、誕生月、誕生日 ≦ 算出日 だったら、
誕生日を向かえているので 年齢+1する
計算結果
誕生日 | 算出日 | 年齢 |
---|---|---|
1960/11/11 | 2020/11/09 | 59 |
1960/11/11 | 2020/11/10 | 59 |
1960/11/11 | 2020/11/11 | 60 |
1960/11/11 | 2020/11/12 | 60 |
1960/11/11 | 2020/11/13 | 60 |
確かに今年、定年ですね(与件)
しめしめ、これで年齢がバッチリ計算できるぜ!と思ったのですが、そう言えば甥っこが閏年の2月29日生まれだったな、4年に一度2月29日とし、平年は2月28日として同様なロジックで行けばいいんだね!と、試行錯誤したのですが、どうも按配が悪い。
結局、生年月日が2月29日の場合のロジックは別にする事にしました。
コレクション:Enumerable.Range(誕生日.AddDays(1).Year, 算出日.Year - 誕生日.AddDays(1).Year + 1)
要素:Int32型
⇒ここは変わらない
条件: 誕生日.CompareTo(New DateTime(Y, 2, 28) .AddDays(CType(DateTime.IsLeapYear(y), Int32) * -1)).Equals(-1)
AndAlso Not 算出日.CompareTo(New DateTime(Y, 2, 28) .AddDays(CType(DateTime.IsLeapYear(y), Int32) * -1)).Equals(-1)
⇒誕生日 < (計算年、2、28) * 閏年要素 ≦ 算出日 だったら、
誕生日を向かえているので 年齢+1する
はい!ここで変なことをやっていますね?閏年要素(.AddDaysメソッドの引数)のところです!
.AddDays(CType(DateTime.IsLeapYear(y), Int32) * -1))
DateTime.IsLeapYear(Y)メソッドは、指定した年(Y)が閏年だったらTrueを、そうでなかったらFalseを返します。True/Falseは数値として表すと、-1/0となるので、CTypeでInt32型に変換して、更に**-1を乗する事で、閏年(True)なら1**、平年(False)なら0となり、その年の2月の晦日が算出できるのです。
年 | 閏年 | 数値 | AddDays | 2月晦日 |
---|---|---|---|---|
2019 | False | 0 | 0 | 2019/2/28 |
2020 | True | -1 | 1 | 2019/2/29 |
###【結果】
誕生日 | 算出日 | 年齢 |
---|---|---|
2019/02/28 | 2024/02/27 | 4 |
*2024/02/28 | 5 | |
2024/02/29 | 5 | |
2024/03/01 | 5 | |
2024/03/02 | 5 | |
2019/02/28 | 2025/02/26 | 5 |
2025/02/27 | 5 | |
*2025/02/28 | 6 | |
2025/03/01 | 6 | |
2025/03/02 | 6 | |
2020/02/28 | 2024/02/27 | 3 |
*2024/02/28 | 4 | |
2024/02/29 | 4 | |
2024/03/01 | 4 | |
2024/03/02 | 4 | |
2020/02/28 | 2025/02/26 | 4 |
2025/02/27 | 4 | |
*2025/02/28 | 5 | |
2025/03/01 | 5 | |
2025/03/02 | 5 | |
2020/02/29 | 2024/02/27 | 3 |
2024/02/28 | 3 | |
*2024/02/29 | 4 | |
2024/03/01 | 4 | |
2024/03/02 | 4 | |
2020/02/29 | 2025/02/26 | 4 |
2025/02/27 | 4 | |
*2025/02/28 | 5 | |
2025/03/01 | 5 | |
2025/03/02 | 5 |
####【参考】年齢計算ニ関スル法律より抜粋
年齢計算ニ関スル法律(ねんれいけいさんにかんするほうりつ)は、年齢の計算方法を定める日本の法律である。民法の附属法の一つに位置付けられる。法令番号は明治35年法律第50号、1902年(明治35年)12月2日に公布され、同年12月22日に施行された。
年齢計算ニ関スル法律は、年齢は出生の日から起算するものとし、初日不算入の例外を定めている(年齢計算ニ関スル法律第1項)。そして、その期間は起算日応当日の前日に満了する(年齢計算ニ関スル法律第2項、民法143条準用(同条2項参照))[2]。
以上の条文から、年齢は生まれた日を0歳とし、生まれた年の翌年以降、起算日に応当する日の前日が満了するたびに1歳ずつ加算する。つまり、加齢する時刻は誕生日前日が満了する「午後12時」(24時0分0秒)と解されている[3][4](「前日午後12時」と「当日午前0時」は時刻としては同じだが、属する日は異なることに注意)。
したがって、閏日である2月29日生まれの者は4年に1度しか加齢しないというわけではなく、毎年2月28日の午後12時に加齢することになる
##おわりに
いかがでした?
▼DateTime型はExcelシート上の日付でフィルタリング範囲に使ってみたり、先の例のように業務で管理単位とするなど、様々なシーンで扱うことが多い型です。
▼閏年を意識するのは意外と大変で、4年に一度の閏年でも、100年に一度は平年となり、でも400年に一度は閏年になると言う。ここは.IsLeapYear()メソッドを信じてロジックを組みましょう!
※来る100年に一度の平年は、2100年であり、更に400年に一度の閏年は2400年。ですので、2000年をはさむ年齢計算はレアな状態下であるのです。
是非UiPathでのロボ開発の一助になればと思っています。
ありがとうございました!