30

Possible Duplicate:
How do I calculate someone's age based on a DateTime type birthday?

I want to write an ASP.NET helper method which returns the age of a person given his or her birthday.

I've tried code like this:

public static string Age(this HtmlHelper helper, DateTime birthday)
{
    return (DateTime.Now - birthday); //??
}

But it's not working. What is the correct way to calculate the person's age based on their birthday?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
nacho10f
  • 5,816
  • 6
  • 42
  • 73

4 Answers4

48

Stack Overflow uses such a function to determine the age of a user.

How do I calculate someone's age based on a DateTime type birthday?

The given answer is

DateTime now = DateTime.Today;
int age = now.Year - bday.Year;
if (now < bday.AddYears(age)) 
    age--;

So your helper method would look like:

public static string Age(this HtmlHelper helper, DateTime birthday)
{
    DateTime now = DateTime.Today;
    int age = now.Year - birthday.Year;
    if (now < birthday.AddYears(age)) 
        age--;

    return age.ToString();
}

Today, I use a different version of this function to include a date of reference. This allow me to get the age of someone at a future date or in the past. This is used for our reservation system, where the age in the future is needed.

public static int GetAge(DateTime reference, DateTime birthday)
{
    int age = reference.Year - birthday.Year;
    if (reference < birthday.AddYears(age))
        age--;

    return age;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pierre-Alain Vigeant
  • 22,635
  • 8
  • 65
  • 101
  • Why not just `new DateTime(DateTime.Now.Subtract(birthDate.Ticks).Year - 1`? – Steven Sudit Feb 03 '10 at 20:24
  • On a side note, what's the right behavior for birthdates in the future? Return a negative number? Throw? Also, do people literally born yesterday have an age of 0 years? – Steven Sudit Feb 03 '10 at 20:28
  • @Steven Someone that is not yet born should always have a age of 0, imo. You only have 1 year at the end of that year. That's the same debate that occurred on y2k. We celebrated the change in date, but the 2000ieth year was complete only at the start of 2001, so we should have been celebrating the 2000ieth year at the start of 2001 not at the start of 2000. – Pierre-Alain Vigeant Feb 03 '10 at 20:40
  • Perhaps if we wanted to return 0 for future births, we could do something like: `return (new DateTime(Math.Max(0, DateTime.Now.Substract(birthDate.Ticks)).Year - 1)` – Steven Sudit Feb 03 '10 at 22:00
  • There are some cultures that count the first year of the baby's life as #1. – BillW Feb 03 '10 at 22:49
  • And still others that count birthdays in terms of reaching a specific time of year. I was restricting myself to en-us, though. :-) – Steven Sudit Feb 04 '10 at 15:05
  • Be very careful when working with Dates. Remember DateTime is not a date - it represents point in time. DateTime can be of kind Unspecified, Local or UTC if you mix those in calculations you'll end up with nasty bugs. Check out Jon Skeet's https://nodatime.org/ for more information, – Mihail Shishkov Mar 30 '18 at 20:37
6

Another clever way from that ancient thread:

int age = (
    Int32.Parse(DateTime.Today.ToString("yyyyMMdd")) - 
    Int32.Parse(birthday.ToString("yyyyMMdd"))) / 10000;
Community
  • 1
  • 1
Rubens Farias
  • 57,174
  • 8
  • 131
  • 162
2

I do it like this:

(Shortened the code a bit)

public struct Age
{
    public readonly int Years;
    public readonly int Months;
    public readonly int Days;

}

public Age( int y, int m, int d ) : this()
{
    Years = y;
    Months = m;
    Days = d;
}

public static Age CalculateAge ( DateTime birthDate, DateTime anotherDate )
{
    if( startDate.Date > endDate.Date )
        {
            throw new ArgumentException ("startDate cannot be higher then endDate", "startDate");
        }

        int years = endDate.Year - startDate.Year;
        int months = 0;
        int days = 0;

        // Check if the last year, was a full year.
        if( endDate < startDate.AddYears (years) && years != 0 )
        {
            years--;
        }

        // Calculate the number of months.
        startDate = startDate.AddYears (years);

        if( startDate.Year == endDate.Year )
        {
            months = endDate.Month - startDate.Month;
        }
        else
        {
            months = ( 12 - startDate.Month ) + endDate.Month;
        }

        // Check if last month was a complete month.
        if( endDate < startDate.AddMonths (months) && months != 0 )
        {
            months--;
        }

        // Calculate the number of days.
        startDate = startDate.AddMonths (months);

        days = ( endDate - startDate ).Days;

        return new Age (years, months, days);
}

// Implement Equals, GetHashCode, etc... as well
// Overload equality and other operators, etc...

}

Community
  • 1
  • 1
Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
-3

I don't really understand why you would make this an HTML Helper. I would make it part of the ViewData dictionary in an action method of the controller. Something like this:

ViewData["Age"] = DateTime.Now.Year - birthday.Year;

Given that birthday is passed into an action method and is a DateTime object.

Jake Rios
  • 172
  • 4
  • 4
    doesn't work if someone was born in `'2009-12-31'`; in `'2010-01-01'` already have one year? – Rubens Farias Feb 03 '10 at 20:12
  • As said it is always correct if the person is born on the first of January. In any other case there will be dates where the result is wrong if ther current Month/Day isn't after the Month/Day of the birthdate. – Athanasios Kataras Nov 04 '13 at 22:46