Categories
.net c# datetime

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

2144

Given a DateTime representing a person’s birthday, how do I calculate their age in years?

10

  • 175

    what all of the answers so far have missed is that it depends where the person was born and where they are right now.

    – Yaur

    May 21, 2011 at 7:34

  • 53

    @Yaur: Just convert the time of now + birth into GMT/UTC, age is only a relative value, hence timezones are irrelevant. For determining the user’s current timezone, you can use GeoLocating.

    Oct 3, 2011 at 10:20

  • 9

    If we’re taking into consideration @Yaur ‘s suggestion of cross-timezone calculations, should Day Light Saving Time affect the calculation in any manner?

    – DDM

    Jul 11, 2015 at 3:42

  • 4

    Note that for someone less than one year old, their age is given in days, weeks, or months. The transition time for the units may be domain-specific.

    Nov 10, 2017 at 22:09

  • 6

    As we can all see there is no definitive definition of age. Many women I’ve met tends to round up their living time to a complete year until twenty-something, then they start rounding down. I was born Jan 3rd, so I just subtract current year from my birth year, no matter what day it is. some people think if you were born on a leap day, you age in 1/4 ratio. What if you were born on at a leap second? does an 8 months old baby counted as 1? If I fly to west, do I get younger? If my hearts stops for a minute, should I include that in calculation?

    Oct 15, 2020 at 16:27

2347

An easy to understand and simple solution.

// Save today's date.
var today = DateTime.Today;

// Calculate the age.
var age = today.Year - birthdate.Year;

// Go back to the year in which the person was born in case of a leap year
if (birthdate.Date > today.AddYears(-age)) age--;

However, this assumes you are looking for the western idea of the age and not using East Asian reckoning.

4

  • 92

    This answer does not work with all locales and all ages. Several countries have skipped dates after the birth of current living people, including Russia (1918), Greece (1924) and Turkey (1926).

    – Lars D

    Nov 9, 2009 at 22:09

  • 39

    Actually, it’s still not entirely correct. This code presumes that ‘bday’ is the date-portion of a DateTime. It’s an edge-case (I guess most people will just be passing dates and not date-times), but if you pass in a birthday as a date-and-time where the time is greater than 00:00:00 then you’ll run into the bug Danvil pointed out. Setting bday = bday.Date fixes this.

    – Øyvind

    Nov 16, 2010 at 15:37

  • 7

    this is 12 years but why don’t you just minus brithday – today later go for timespan and you can get it without an if.

    – AbbathCL

    Mar 17, 2021 at 6:19

  • @AbbathCl: Timespan has no years.

    – Wouter

    Jul 22 at 10:20

1086

This is a strange way to do it, but if you format the date to yyyymmdd and subtract the date of birth from the current date then drop the last 4 digits you’ve got the age 🙂

I don’t know C#, but I believe this will work in any language.

20080814 - 19800703 = 280111 

Drop the last 4 digits = 28.

C# Code:

int now = int.Parse(DateTime.Now.ToString("yyyyMMdd"));
int dob = int.Parse(dateOfBirth.ToString("yyyyMMdd"));
int age = (now - dob) / 10000;

Or alternatively without all the type conversion in the form of an extension method. Error checking omitted:

public static Int32 GetAge(this DateTime dateOfBirth)
{
    var today = DateTime.Today;

    var a = (today.Year * 100 + today.Month) * 100 + today.Day;
    var b = (dateOfBirth.Year * 100 + dateOfBirth.Month) * 100 + dateOfBirth.Day;

    return (a - b) / 10000;
}

10

  • 12

    Actually this is great for usage on MS-SQL with datetime-fields (total days since 01-011900)

    – Patrik

    Jul 3, 2015 at 12:01

  • 9

    @numerek Please post your suggested modifications as their own answer. For what it’s worth, the current year times 10000 is nowhere near an integer overflow, by two orders of magnitude. 20,150,000 vs 2,147,483,648

    Sep 3, 2015 at 20:23

  • 2

    This answer assumes that leap day babies have their birthdays on 1st March on non-leap years.

    Feb 13, 2018 at 9:38

  • 12

    @LongChalk 20180101 - 20171231 = 8870. Drop the last 4 digits and you have (an implied) 0 for the age. How did you get 1?

    – Rufus L

    Jun 14, 2018 at 20:36


  • 2

    @RufusL Its 0, not 1. floor(8870 / 10000) == 0. You are “counting” ten thousands, and at 8870 you have zero ten thousands.

    Jul 3, 2018 at 18:13

413

Here is a test snippet:

DateTime bDay = new DateTime(2000, 2, 29);
DateTime now = new DateTime(2009, 2, 28);
MessageBox.Show(string.Format("Test {0} {1} {2}",
                CalculateAgeWrong1(bDay, now),      // outputs 9
                CalculateAgeWrong2(bDay, now),      // outputs 9
                CalculateAgeCorrect(bDay, now),     // outputs 8
                CalculateAgeCorrect2(bDay, now)));  // outputs 8

Here you have the methods:

public int CalculateAgeWrong1(DateTime birthDate, DateTime now)
{
    return new DateTime(now.Subtract(birthDate).Ticks).Year - 1;
}

public int CalculateAgeWrong2(DateTime birthDate, DateTime now)
{
    int age = now.Year - birthDate.Year;

    if (now < birthDate.AddYears(age))
        age--;

    return age;
}

public int CalculateAgeCorrect(DateTime birthDate, DateTime now)
{
    int age = now.Year - birthDate.Year;

    if (now.Month < birthDate.Month || (now.Month == birthDate.Month && now.Day < birthDate.Day))
        age--;

    return age;
}

public int CalculateAgeCorrect2(DateTime birthDate, DateTime now)
{
    int age = now.Year - birthDate.Year;

    // For leap years we need this
    if (birthDate > now.AddYears(-age)) 
        age--;
    // Don't use:
    // if (birthDate.AddYears(age) > now) 
    //     age--;

    return age;
}

5

  • 39

    While this code works, it asserts that a person born on a leap day attains the next year of age on March 1st on non-leap years, rather than on February 28th. In reality, either option may be correct. Wikipedia has something to say about this. So while your code is not “wrong”, neither is the accepted solution.

    Aug 17, 2014 at 5:44

  • 26

    @MattJohnson I think that’s actually correct. If my bday was Feb 29, then Feb 28 my bday hasn’t passed, and I should still be the same age as on Feb 27. On March 1, however, we have passed my bday and I should be the next age. In the US, a business that sells alcohol will have a sign that says something like “If you were born after this day in YYYY, you can’t purchase alcohol” (where YYYY changes every year). That means that someone born on Feb 29 cannot buy alcohol on Feb 28 in the year they turn 21 (most places), and lends support to the idea that they are not a year older until March 1.

    – jfren484

    Jul 12, 2016 at 17:18

  • 7

    @jfren484 – read the Wikipedia article. It varies considerably across jurisdictions.

    Jul 12, 2016 at 19:26

  • 13

    @jfren484 Your claim has absolutely nothing to do with philosophy; but everything to do with your own personal feeling. When a person born on 29 Feb “ages” is largely unimportant unless the age forms a ‘legal age boundary’ (e.g. Can buy alcohol, vote, get pension, join army, get driving license). Consider US drinking age (21 years): For most people that’s 7670 days. It’s 7671 days if born before 29 Feb in leap year or from 1 Mar before leap year. If born on 29 Feb: 28 Feb is 7670 days and 1 Mar is 7671 days. The choice is arbitrary it can go either way.

    Mar 4, 2017 at 10:06

  • 9

    @CraigYoung You don’t understand what I meant by philosophically. I used that term as a contrast to legally. If one is writing an application that needs to know the legal age of a person, then all they need to know is how the legal jurisdictions that their application is used in/for treat people born on Feb 29. If, however, we’re talking about how that should be treated, then that is by definition, philosophy. And yes, the opinion I gave is my own opinion, but as I said, I think it would be easier to argue for March 1 than it would be for Feb 28.

    – jfren484

    Mar 4, 2017 at 18:45