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)) / 372We know that what we need is either
Yn-Ybif the date has already been reached,Yn-Yb-1if it has not.a) If
Mn, we have -341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30
-371 <= 31*(Mn - Mb) + (Dn - Db) <= -1With integer division
(31*(Mn - Mb) + (Dn - Db)) / 372 = -1b) If
Mn=MbandDn, we have 31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1With integer division, again
(31*(Mn - Mb) + (Dn - Db)) / 372 = -1c) If
Mn>Mb, we have31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30
1 <= 31*(Mn - Mb) + (Dn - Db) <= 371With integer division
(31*(Mn - Mb) + (Dn - Db)) / 372 = 0d) If
Mn=MbandDn>Db, we have31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 30With integer division, again
(31*(Mn - Mb) + (Dn - Db)) / 372 = 0e) If
Mn=MbandDn=Db, we have31*(Mn - Mb) + Dn-Db = 0and therefore
(31*(Mn - Mb) + (Dn - Db)) / 372 = 0