Given a DateTime
representing a person\'s birthday, how do I calculate their age in years?
Here's yet another answer:
public static int AgeInYears(DateTime birthday, DateTime today)
{
return ((today.Year - birthday.Year) * 372 + (today.Month - birthday.Month) * 31 + (today.Day - birthday.Day)) / 372;
}
This has been extensively unit-tested. It does look a bit "magic". The number 372 is the number of days there would be in a year if every month had 31 days.
The explanation of why it works (lifted from here) is:
Let's set
Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day
age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 372
We know that what we need is either
Yn-Yb
if the date has already been reached,Yn-Yb-1
if it has not.a) If
Mn
, we have -341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30
-371 <= 31*(Mn - Mb) + (Dn - Db) <= -1
With integer division
(31*(Mn - Mb) + (Dn - Db)) / 372 = -1
b) If
Mn=Mb
andDn
, we have 31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1
With integer division, again
(31*(Mn - Mb) + (Dn - Db)) / 372 = -1
c) If
Mn>Mb
, we have31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30
1 <= 31*(Mn - Mb) + (Dn - Db) <= 371
With integer division
(31*(Mn - Mb) + (Dn - Db)) / 372 = 0
d) If
Mn=Mb
andDn>Db
, we have31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 3
0With integer division, again
(31*(Mn - Mb) + (Dn - Db)) / 372 = 0
e) If
Mn=Mb
andDn=Db
, we have31*(Mn - Mb) + Dn-Db = 0
and therefore
(31*(Mn - Mb) + (Dn - Db)) / 372 = 0