You would think that calculating the age of a person based on their date of birth would be simple, but it's more tricky than that. Like most problems in programming, things are never what they seem at first glance.
The .NET framework has some greate objects for working with dates and time - System.DateTime and System.TimeSpan, and it's trivial to do a calculation like the following.
public int CalculateAge(DateTime birthDate)
{
return DateTime.Now.Year - birthDate.Year;
}
Our return value has the correct calculation of the difference in years between the current date and the birth date, but that isn't what a typical person considers an age. The following test cases will show that this function isn't correct.
[TestMethod]
public void TestAgeCalculation()
{
DateTime dob = DateTime.Now.AddYears(-1);
// born a year ago yesterday
dob = DateTime.Now.AddDays(-1);
Assert.AreEqual(CalculateAge(dob), 1);
// born a year ago today
dob = DateTime.Now.AddDays(1);
Assert.AreEqual(CalculateAge(dob), 1);
// born a year ago tomorrow
dob = DateTime.Now.AddDays(1);
Assert.AreEqual(CalculateAge(dob), 0);
}
The third test case fails because age doesn't automatically equal the difference in years. Another solution that comes quickly to mind is to get a TimeSpan which is the difference between now and the date of birth, but there's no method that converts a TimeSpan to the number of years. What you
can get from a TimeSpan is the number of days, which you can then divide to get years.
public int CalculateAge(DateTime birthDate)
{
TimeSpan ageTime =
DateTime.Now.Subtract(birthDate);
return Convert.ToInt32(Math.Floor(
ageTime.Days / 365.25));
}
This fails too because we consider ourselves to be a year older on our birth day, even though we're actually not a year older until the day after our birthday. Also, I don't really like the division by 365.25 because it's not entirely accurate. Of course, that's all ignoring the time of birth in the equation.
Here is what I finally came up with to accurately calculate an age from date of birth.
public int CalculateAge(DateTime dob)
{
int years = DateTime.Now.Year - dob.Year;
if (dob.AddYears(years) > DateTime.Now)
years--;
return years;
}
Definitely not all that complicated, but more tricky than I imagined it would be when I started to tackle the solution. This is one of those things that all programmers run into at least a handful of times during their career and, I'd hope, take some time to make sure their code is accurate, but it's easy to just throw code out there that works 98% of the time.
Labels: c#