UiPath：年齢の取得

## 皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん＊＊は！はなっち！です。

前回、AndAlso演算子と言うのを解説しました。これを効果的に使えるシーンってなんだろう？と考えた時、年齢を算出するxamlはどうか？と思い立って、早速作ってみました。

###年齢はどうやって計算
年齢はどうやって計算するか。まぁ普通なら算出年から生年を引いて、誕生日を迎えていなかったら-1するのが正攻法なのでしょうが、今回は生年から算出年まで繰り返してやってみようと思うのです。

さて、入力には、DateTime型の誕生日と、DateTime型の算出日。出力は年齢ですね。DateTime型の算出日が未設定であったら、Nowとするようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/d6018d2b-6341-3bc6-23fe-7827a9915839.png)

DateTime型は、未設定状態だと0001/01/01 00:00:00となるので、.Year()で得た年が1だったらと言う条件ですね。

あとは簡単に、生年月日の年から算出日の年までを繰り返し、その年の誕生日が生年月日より大きく、算出日以下である時に年齢を＋１すればいいのですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/34c6feda-37b3-3745-570f-39f9bc2b981d.png)

コレクション：`Enumerable.Range(誕生日.AddDays(1).Year, 算出日.Year - 誕生日.AddDays(1).Year + 1)`
要素：Int32型
⇒誕生日の翌日の年を始値とし、算出日の年から始値を引き、＋１する。

条件：      `誕生日.CompareTo(New DateTime(Y, 誕生日.Month, 誕生日.Day)).Equals(-1)`
`AndAlso Not 算出日.CompareTo(New DateTime(Y, 誕生日.Month, 誕生日.Day)).Equals(-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日生まれだったな、４年に一度2月29日とし、平年は2月28日として同様なロジックで行けばいいんだね！と、試行錯誤したのですが、どうも按配が悪い。

結局、生年月日が2月29日の場合のロジックは別にする事にしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/3366df16-46f4-6ec0-a1d4-f78e7a4ea784.png)

コレクション：`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) * **閏年要素**　≦　算出日　だったら、
　誕生日を向かえているので　年齢＋１する 

はい！ここで変なことをやっていますね？**閏年要素**(.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

####【参考】[年齢計算ニ関スル法律より抜粋](https://ja.wikipedia.org/wiki/%E5%B9%B4%E9%BD%A2%E8%A8%88%E7%AE%97%E3%83%8B%E9%96%A2%E3%82%B9%E3%83%AB%E6%B3%95%E5%BE%8B)
年齢計算ニ関スル法律（ねんれいけいさんにかんするほうりつ）は、年齢の計算方法を定める日本の法律である。民法の附属法の一つに位置付けられる。法令番号は明治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でのロボ開発の一助になればと思っています。

ありがとうございました！