By Jeff Atwood


2008-07-31 23:40:59 8 Comments

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

30 comments

@Mike Polen 2008-08-04 16:50:06

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 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 age and not using East Asian reckoning.

@JAG 2009-01-22 10:29:38

Just wanted to comment on DateTime.Now performance. If you don't need an accurate time zone value, use DateTime.UtcNow it's much faster.

@Tristan Warner-Smith 2009-07-24 18:04:27

Given we're talking birthdays you can just use DateTime.Today given the time part has no relevance.

@Lars D 2009-11-09 22:09:27

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).

@e-satis 2009-11-16 16:35:59

So we have a different age according to different countries and calendar ? What a scoop...

@Shimmy 2009-12-14 00:37:05

@JAG: DateTime.Today should be even faster.

@Øyvind 2010-11-16 15:37:18

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.

@cdiggins 2011-07-16 17:53:57

The last line made me think too much. Instead how about: if (bday.AddYears(age) > now) age--; This seems to be a more intuitive expression.

@Mike Polen 2011-07-18 18:04:50

Good idea cdiggins, but it doesn't work as bday.AddYears(age) when age is 2/29 returns 2/28 on years that are not leap years...keep trying

@NKCSS 2012-08-16 15:15:54

Or just do if (BirthDate.DayOfYear > Today.DayOfYear); no need to forther modify the date variables

@Guvante 2012-08-21 18:47:47

@NKCSS: That does not handle the leap year correctly. My testing shows that only if (bday > now.AddYears(-age)) works. Since DayOfYear returns 61 in 2012 and 60 in 2011 for March 1.

@devuxer 2012-12-12 02:06:20

@Danvil, is it really wrong? Take a simpler example. Birthday = 2000/02/29, Today = 2001/02/28. Days elapsed: 365. Isn't that one year, and therefore, isn't the person one year old on the 28th? Or is the definition of a year 365-1/4 days? I'm just sayin', it's complicated.

@Nolonar 2013-01-31 10:55:22

Wouldn't it be easier to just do DateTime dateDifference = subject.Birthday - DateTime.Now; int age = dateDifference.Year;? Also, I don't think age depends on leap years. After all, a year is defined as 365<x<366 days, leap years don't make you any day younger.

@Nolonar 2013-01-31 11:03:09

I can't edit my comment anymore, so here's my correction: TimeSpan difference = subject.Birthday - DateTime.Now; int age = difference.Days; If you want the age in years, you could always add int ageInYears = age / 365;

@cja 2013-02-13 15:08:20

@LarsD "Several countries have skipped dates after the birth of current living people" <- What do you mean?

@bPratik 2013-02-14 18:04:55

@cja - It means that some countries did some funnies years ago to sync up calendars and remove discrepancies! en.wikipedia.org/wiki/Gregorian_calendar may speak more about it, I haven't fully read. The reference to 'Current People' is simply to state that the adjustments happened in the 20th century (1901-2000). A lot of people are still alive from that period! :)

@Shaik Raffi 2013-11-05 11:34:11

DateTime birthdate = new DateTime(2012, 11, 5); DateTime now = DateTime.Now; int years = now.Year - birthdate.Year; if (now.Month < birthdate.Month || (now.Month == birthdate.Month && now.Day < birthdate.Day)) years--; Console.WriteLine(years.ToString()); Console.ReadLine();

@Gusdor 2013-11-05 13:04:37

@LarsD so what you are saying is that there is no way to calculate people's ages? Rubbish. They messed with their calendar, they can adapt. Even if you could do a library to calculate cross calender based on locale, a) where do you source this info b) is it actually worth it?

@Dhaval Panchal 2013-12-03 10:13:16

This code is not calculating the nearest age. Here, is the code: var ts = DateTime.Now - new DateTime(1988, 3, 19); var age = Math.Round(ts.Days / 365.0);

@Travis 2014-05-17 00:02:51

int age = DateTime.Today.Year - bday.Year; age = bday > DateTime.Today.AddYears(-age)) ? age-- : age;

@gldraphael 2015-06-08 17:26:27

why not use TimeSpan?

@alpham8 2015-07-11 17:23:13

is this solution also looking about months? Otherwise it clould +/- 1 year

@Luke T O'Brien 2015-08-14 08:52:16

This answer doesn't take month into account - If I was born in December 1990 and today is March 2000 my age is 9 and not 10 because I haven't had my birthday yet

@user743382 2015-10-12 07:38:26

@LukeTO'Brien The if (bday > today.AddYears(-age)) age--; part in this answer is supposed to take care of that. age would be 10 at that point based on the difference in year numbers. If the birthday (December 1990) is later than 10 years ago (which would be March 1990), which it is, then age gets decremented to 9. Are you saying that doesn't work for you?

@Rob 2015-12-04 02:31:31

@TristanWarner-Smith Well, technically it does. If you're born Jan 1st 1990 at 1pm, you're 0 at Jan 1st 12:59 1991, but 1 at Jan 1st 1:01pm 1991.

@Tristan Warner-Smith 2015-12-04 10:17:59

@Rob I guess you're right, but it's a question of precision, usually your birthday counts as any time from 00:00 - 23:59:59 on a specific day.

@displayName 2016-03-11 16:48:41

Quick Fun Fact: This answer has featured in this pluralsight course's, Module 5 - Chapter 3.

@jfren484 2016-07-12 16:56:37

@Rob In the USA, at least, it is accepted that on your birthday, no matter when in the day you were born, you are said to be the next age in years. Even if one was born at 11:59 pm on January 1, at the New Year's party when the ball drops, everyone would accept that your age had changed even though you are still almost 24 hours short of the time of your birth. :) Legally, an individual is said to be a year older on their birthday as well. Whether it's being 16 to drive, or 21 to drink, or 18 to vote. It doesn't matter what time you were born. On your birthday you're a year older.

@Daniel Liuzzi 2016-09-05 14:14:39

In England and Wales or in Hong Kong, a person born on February 29 will have legally reached 18 years old on March 1. If he or she was born in Taiwan he or she legally becomes 18 on February 28, a day earlier. (Wikipedia) So birthdate.AddYears(age) > today and birthdate > today.AddYears(-age) are both correct and incorrect, depending on the jurisdiction.

@Avdhut Vaidya 2017-04-02 17:48:34

your last condition birthdate > now.AddYears(-age) was something i got quickly because of your post!! thanks a lot

@Legends 2017-10-11 19:42:14

Is this solution above with over 1400 upvotes correct, because I can read from the comments section that there are some issues with this solution...?

@user743382 2018-02-22 12:11:14

@Legends It's making more assumptions than have been pointed out in the answer, and it's correct for your case if and only if those assumptions hold for your case. Without knowing your case, it's impossible for anyone other than yourself to turn that into a yes or no answer.

@Melbourne Developer 2018-04-09 02:48:58

The concept of measuring age in years is just a filthy lie because it doesn't take in to account leap years. We should be measuring age in days.

@Nathan Cooper 2018-06-11 15:37:24

If it's your 30th birthday this afternoon, are you 30 in the morning? I would say yes. Which means it should be if (birthdate.Date > today.AddYears(-age).Date) age--;?

@Mr. Leeds 2018-06-28 03:45:29

This kind of answer not only answers your question. It also leaves another question. I didn't know about that East Asian Reckoning until i found this answer.

@Wouter 2018-11-26 00:27:37

Note that this requires both datetime values to be on the same timezone.

@Kaval Patel 2017-10-31 12:09:08

To calculate how many years old a person is,

DateTime dateOfBirth;

int ageInYears = DateTime.Now.Year - dateOfBirth.Year;

if (dateOfBirth > today.AddYears(-ageInYears )) ageInYears --;

@Tobias 2018-06-26 06:32:15

This would mean that someone born on December 31st in 2000 turned 18 on January 1st 2018! 2018-2000 = 18

@Kaval Patel 2018-07-25 12:01:01

Thanks for reminding me I have updated my answer now, at that time I am forgetting to add the last line. So Thank you for correcting me. :)

@Matt Johnson 2013-12-21 04:53:09

This classic question is deserving of a Noda Time solution.

static int GetAge(LocalDate dateOfBirth)
{
    Instant now = SystemClock.Instance.Now;

    // The target time zone is important.
    // It should align with the *current physical location* of the person
    // you are talking about.  When the whereabouts of that person are unknown,
    // then you use the time zone of the person who is *asking* for the age.
    // The time zone of birth is irrelevant!

    DateTimeZone zone = DateTimeZoneProviders.Tzdb["America/New_York"];

    LocalDate today = now.InZone(zone).Date;

    Period period = Period.Between(dateOfBirth, today, PeriodUnits.Years);

    return (int) period.Years;
}

Usage:

LocalDate dateOfBirth = new LocalDate(1976, 8, 27);
int age = GetAge(dateOfBirth);

You might also be interested in the following improvements:

  • Passing in the clock as an IClock, instead of using SystemClock.Instance, would improve testability.

  • The target time zone will likely change, so you'd want a DateTimeZone parameter as well.

See also my blog post on this subject: Handling Birthdays, and Other Anniversaries

@Zimano 2019-03-29 13:15:40

Are you affiliated with Noda Time?

@Matt Johnson 2019-03-29 14:05:06

I have made contributions to it, but it is primarily Jon Skeet's.

@user687474 2011-05-13 08:12:55

The following approach (extract from Time Period Library for .NET class DateDiff) considers the calendar of the culture info:

// ----------------------------------------------------------------------
private static int YearDiff( DateTime date1, DateTime date2 )
{
  return YearDiff( date1, date2, DateTimeFormatInfo.CurrentInfo.Calendar );
} // YearDiff

// ----------------------------------------------------------------------
private static int YearDiff( DateTime date1, DateTime date2, Calendar calendar )
{
  if ( date1.Equals( date2 ) )
  {
    return 0;
  }

  int year1 = calendar.GetYear( date1 );
  int month1 = calendar.GetMonth( date1 );
  int year2 = calendar.GetYear( date2 );
  int month2 = calendar.GetMonth( date2 );

  // find the the day to compare
  int compareDay = date2.Day;
  int compareDaysPerMonth = calendar.GetDaysInMonth( year1, month1 );
  if ( compareDay > compareDaysPerMonth )
  {
    compareDay = compareDaysPerMonth;
  }

  // build the compare date
  DateTime compareDate = new DateTime( year1, month2, compareDay,
    date2.Hour, date2.Minute, date2.Second, date2.Millisecond );
  if ( date2 > date1 )
  {
    if ( compareDate < date1 )
    {
      compareDate = compareDate.AddYears( 1 );
    }
  }
  else
  {
    if ( compareDate > date1 )
    {
      compareDate = compareDate.AddYears( -1 );
    }
  }
  return year2 - calendar.GetYear( compareDate );
} // YearDiff

Usage:

// ----------------------------------------------------------------------
public void CalculateAgeSamples()
{
  PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2009, 02, 28 ) );
  // > Birthdate=29.02.2000, Age at 28.02.2009 is 8 years
  PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2012, 02, 28 ) );
  // > Birthdate=29.02.2000, Age at 28.02.2012 is 11 years
} // CalculateAgeSamples

// ----------------------------------------------------------------------
public void PrintAge( DateTime birthDate, DateTime moment )
{
  Console.WriteLine( "Birthdate={0:d}, Age at {1:d} is {2} years", birthDate, moment, YearDiff( birthDate, moment ) );
} // PrintAge

@Matthew Watson 2013-04-22 08:19:51

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<Mb, 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 and Dn<Db, 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 have 31 <= 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 and Dn>Db, we have 31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 30

With integer division, again

(31*(Mn - Mb) + (Dn - Db)) / 372 = 0

e) If Mn=Mb and Dn=Db, we have 31*(Mn - Mb) + Dn-Db = 0

and therefore (31*(Mn - Mb) + (Dn - Db)) / 372 = 0

@nabuchodonossor 2018-05-29 09:43:22

I stumbled into this long and annoying discussion, and your solution is a really nice and small approach. Thanks for keeping it simple

@Nicholas Carey 2010-10-06 01:49:50

The simplest way I've ever found is this. It works correctly for the US and western europe locales. Can't speak to other locales, especially places like China. 4 extra compares, at most, following the initial computation of age.

public int AgeInYears(DateTime birthDate, DateTime referenceDate)
{
  Debug.Assert(referenceDate >= birthDate, 
               "birth date must be on or prior to the reference date");

  DateTime birth = birthDate.Date;
  DateTime reference = referenceDate.Date;
  int years = (reference.Year - birth.Year);

  //
  // an offset of -1 is applied if the birth date has 
  // not yet occurred in the current year.
  //
  if (reference.Month > birth.Month);
  else if (reference.Month < birth.Month) 
    --years;
  else // in birth month
  {
    if (reference.Day < birth.Day)
      --years;
  }

  return years ;
}

I was looking over the answers to this and noticed that nobody has made reference to regulatory/legal implications of leap day births. For instance, per Wikipedia, if you're born on February 29th in various jurisdictions, you're non-leap year birthday varies:

  • In the United Kingdom and Hong Kong: it's the ordinal day of the year, so the next day, March 1st is your birthday.
  • In New Zealand: it's the previous day, February 28th for the purposes of driver licencing, and March 1st for other purposes.
  • Taiwan: it's February 28th.

And as near as I can tell, in the US, the statutes are silent on the matter, leaving it up to the common law and to how various regulatory bodies define things in their regulations.

To that end, an improvement:

public enum LeapDayRule
{
  OrdinalDay     = 1 ,
  LastDayOfMonth = 2 ,
}

static int ComputeAgeInYears(DateTime birth, DateTime reference, LeapYearBirthdayRule ruleInEffect)
{
  bool isLeapYearBirthday = CultureInfo.CurrentCulture.Calendar.IsLeapDay(birth.Year, birth.Month, birth.Day);
  DateTime cutoff;

  if (isLeapYearBirthday && !DateTime.IsLeapYear(reference.Year))
  {
    switch (ruleInEffect)
    {
      case LeapDayRule.OrdinalDay:
        cutoff = new DateTime(reference.Year, 1, 1)
                             .AddDays(birth.DayOfYear - 1);
        break;

      case LeapDayRule.LastDayOfMonth:
        cutoff = new DateTime(reference.Year, birth.Month, 1)
                             .AddMonths(1)
                             .AddDays(-1);
        break;

      default:
        throw new InvalidOperationException();
    }
  }
  else
  {
    cutoff = new DateTime(reference.Year, birth.Month, birth.Day);
  }

  int age = (reference.Year - birth.Year) + (reference >= cutoff ? 0 : -1);
  return age < 0 ? 0 : age;
}

It should be noted that this code assumes:

  • A western (European) reckoning of age, and
  • A calendar, like the Gregorian calendar that inserts a single leap day at the end of a month.

@James A. Rosen 2008-08-17 17:14:48

I don't think any of the answers so far provide for cultures that calculate age differently. See, for example, East Asian Age Reckoning versus that in the West.

Any real answer has to include localization. The Strategy Pattern would probably be in order in this example.

@some 2008-12-28 09:15:57

From the wikipedia article that you provided: "In China and Japan it is used for traditional fortune-telling or religion, and it is disappearing in daily life between peoples in the city."

@Justin L. 2010-06-25 09:15:37

@some -- Koreans still use this system primarily.

@Phil Gan 2010-08-05 08:16:14

Actually this concept can be pretty important - people don't like being told their personal information incorrectly. As an example, half of my family lives in Malaysia and half in the UK. Right now my age is considered two years higher when I'm with one side of my family than with the other.

@Dean Rather 2012-11-12 05:56:46

Not only us this system used primarily in Korea, but as a tourist discussing ages with locals, locals will politely refer to yourself an each other by their birth year. I'm not 25, I'm 87. I like this approach better. more of an 'international birthdatetime format'

@Casey 2014-10-14 20:39:46

Even in Korea, while this system is popularly used in casual conversation, for legal purposes (like, say, the drinking age) Western reckoning is used. So I think just flipping a culture switch is a pretty good way to do things you don't intend to.

@phuclv 2015-07-11 00:56:49

In Vietnam, in daily life even when Western system is used, age is calculated merely by subtracting the years. Date is excluded

@GrandOpener 2015-07-11 16:02:22

The wikipedia article claims "China [has] switched over to the western reckoning system," but when I was living in China even as late as earlier this year (2015), the people I was around in northern Guangdong were using the "East Asian Age Reckoning" system exclusively in informal settings, and also using it officially for determining when a child would enter school. (Bonus fun points: official IDs usually list birth dates using the lunar calendar date, not the Gregorian one.) Clearly the situation is more complicated than just picking one system.

@Lassi Kinnunen 2018-03-21 03:57:24

In thailand your age starts at 1 in common speak. soo.. uh. just be careful when asking for the age, okay. and the ID cards use the thai years(currently 2561).

@krowe2 2018-04-03 14:25:48

For those who haven't figured it out yet, this discussion is not only (mostly) false but also completely pointless. The OP didn't ask how people in X culture calculate age. It asks how the OP should do it. That question does have has a singular answer which is the same as every one here has (or tried to) posted. This answer assumes that the age is being used to display to end users which is a leap too far. Also, if you store locale aware ages and then later want to do further calculations based on that age, well, that's a nightmare you deserve for being a moron. This answer should be an *.

@Moshe L 2012-01-11 08:58:06

I want to add Hebrew calendar calculations (or other System.Globalization calendar can be used in the same way), using rewrited functions from this thread:

Public Shared Function CalculateAge(BirthDate As DateTime) As Integer
    Dim HebCal As New System.Globalization.HebrewCalendar ()
    Dim now = DateTime.Now()
    Dim iAge = HebCal.GetYear(now) - HebCal.GetYear(BirthDate)
    Dim iNowMonth = HebCal.GetMonth(now), iBirthMonth = HebCal.GetMonth(BirthDate)
    If iNowMonth < iBirthMonth Or (iNowMonth = iBirthMonth AndAlso HebCal.GetDayOfMonth(now) < HebCal.GetDayOfMonth(BirthDate)) Then iAge -= 1
    Return iAge
End Function

@cdiggins 2011-07-16 18:01:50

I've made one small change to Mark Soen's answer: I've rewriten the third line so that the expression can be parsed a bit more easily.

public int AgeInYears(DateTime bday)
{
    DateTime now = DateTime.Today;
    int age = now.Year - bday.Year;            
    if (bday.AddYears(age) > now) 
        age--;
    return age;
}

I've also made it into a function for the sake of clarity.

@B2K 2011-05-20 16:48:34

Here's a DateTime extender that adds the age calculation to the DateTime object.

public static class AgeExtender
{
    public static int GetAge(this DateTime dt)
    {
        int d = int.Parse(dt.ToString("yyyyMMdd"));
        int t = int.Parse(DateTime.Today.ToString("yyyyMMdd"));
        return (t-d)/10000;
    }
}

@Yaur 2011-05-21 07:31:13

ugh, don't do this. ToString and int.Parse are both relatively expensive and while i'm anti micro-optimization hiding expensive functions in extension methods that should be trivial operations is not a good idea.

@David Schmitt 2011-05-30 13:32:32

Also, this is a duplicate of ScArcher2's answer: stackoverflow.com/questions/9/…

@B2K 2011-09-08 22:23:29

Yaur, I really like Elmer's solution that relies on DayOfYear, probably more efficient than mine. Note that my goal wasn't to change ScArcher2's algorithm, I felt that would be rude. It was simply to show how to implement an extension method.

@azamsharp 2009-11-28 01:58:57

Would this work?

public override bool IsValid(DateTime value)
{
    _dateOfBirth =  value;
    var yearsOld = (double) (DateTime.Now.Subtract(_dateOfBirth).TotalDays/365);
    if (yearsOld > 18)
        return true;
    return false; 
}

@azamsharp 2009-12-09 02:32:12

Negative rater please explain the reason!!!

@Chris Shouts 2010-05-04 20:57:07

Wow. Why is value an object rather than a DateTime? The method signature should be public override bool Is18OrOlder(DateTime birthday) What about people who were born on February 29? Who said that we were trying to check whether or not the user was at least 18 years old? The question was "how do I calculate someone's age?"

@azamsharp 2010-05-05 00:03:59

How did that happen? I don't even remember putting IsValid as object. It should be DateTime!

@T_Bacon 2018-03-28 08:41:56

Instead of the if statement, why not use return yearsOld > 18;

@Rajeshwaran S P 2009-06-18 10:35:21

Here is a solution.

DateTime dateOfBirth = new DateTime(2000, 4, 18);
DateTime currentDate = DateTime.Now;

int ageInYears = 0;
int ageInMonths = 0;
int ageInDays = 0;

ageInDays = currentDate.Day - dateOfBirth.Day;
ageInMonths = currentDate.Month - dateOfBirth.Month;
ageInYears = currentDate.Year - dateOfBirth.Year;

if (ageInDays < 0)
{
    ageInDays += DateTime.DaysInMonth(currentDate.Year, currentDate.Month);
    ageInMonths = ageInMonths--;

    if (ageInMonths < 0)
    {
        ageInMonths += 12;
        ageInYears--;
    }
}

if (ageInMonths < 0)
{
    ageInMonths += 12;
    ageInYears--;
}

Console.WriteLine("{0}, {1}, {2}", ageInYears, ageInMonths, ageInDays);

@JoshYates1980 2018-06-14 15:58:52

With string concat, this would be possible: 47 Yrs 11 Mo 7 days

@user9359822 2018-02-15 11:17:51

var birthDate = ... // DOB
var resultDate = DateTime.Now - birthDate;

Using resultDate you can apply TimeSpan properties whatever you want to display it.

@wild coder 2018-02-08 15:10:18

Here is the simplest way to calculate someone's age.
Calculating someone's age is pretty straightforward, and here's how! In order for the code to work, you need a DateTime object called BirthDate containing the birthday.

 C#
        // get the difference in years
        int years = DateTime.Now.Year - BirthDate.Year; 
        // subtract another year if we're before the
        // birth day in the current year
        if (DateTime.Now.Month < BirthDate.Month || 
            (DateTime.Now.Month == BirthDate.Month && 
            DateTime.Now.Day < BirthDate.Day)) 
            years--;
  VB.NET
        ' get the difference in years
        Dim years As Integer = DateTime.Now.Year - BirthDate.Year
        ' subtract another year if we're before the
        ' birth day in the current year
        If DateTime.Now.Month < BirthDate.Month Or (DateTime.Now.Month = BirthDate.Month And DateTime.Now.Day < BirthDate.Day) Then 
            years = years - 1
        End If

@Jon Skeet 2018-02-08 15:13:04

"Here is the simplest way to calculate someone's age." That's really not the simplest way. Using Noda Time, it's just int years = Period.Between(birthDate, today).Years;.

@Clearer 2018-04-23 09:42:32

@JonSkeet To be fair, Noda Time is not part of any .Net standard. Given that, this is one of the simplest way to calculate the age of a person, in years.

@DareDevil 2014-01-22 07:23:00

I have a customized method to calculate age, plus a bonus validation message just in case it helps:

public void GetAge(DateTime dob, DateTime now, out int years, out int months, out int days)
{
    years = 0;
    months = 0;
    days = 0;

    DateTime tmpdob = new DateTime(dob.Year, dob.Month, 1);
    DateTime tmpnow = new DateTime(now.Year, now.Month, 1);

    while (tmpdob.AddYears(years).AddMonths(months) < tmpnow)
    {
        months++;
        if (months > 12)
        {
            years++;
            months = months - 12;
        }
    }

    if (now.Day >= dob.Day)
        days = days + now.Day - dob.Day;
    else
    {
        months--;
        if (months < 0)
        {
            years--;
            months = months + 12;
        }
        days += DateTime.DaysInMonth(now.AddMonths(-1).Year, now.AddMonths(-1).Month) + now.Day - dob.Day;
    }

    if (DateTime.IsLeapYear(dob.Year) && dob.Month == 2 && dob.Day == 29 && now >= new DateTime(now.Year, 3, 1))
        days++;

}   

private string ValidateDate(DateTime dob) //This method will validate the date
{
    int Years = 0; int Months = 0; int Days = 0;

    GetAge(dob, DateTime.Now, out Years, out Months, out Days);

    if (Years < 18)
        message =  Years + " is too young. Please try again on your 18th birthday.";
    else if (Years >= 65)
        message = Years + " is too old. Date of Birth must not be 65 or older.";
    else
        return null; //Denotes validation passed
}

Method call here and pass out datetime value (MM/dd/yyyy if server set to USA locale). Replace this with anything a messagebox or any container to display:

DateTime dob = DateTime.Parse("03/10/1982");  

string message = ValidateDate(dob);

lbldatemessage.Visible = !StringIsNullOrWhitespace(message);
lbldatemessage.Text = message ?? ""; //Ternary if message is null then default to empty string

Remember you can format the message any way you like.

@Moises Conejo 2017-12-15 17:27:13

Just use:

(DateTime.Now - myDate).TotalHours / 8766.0

the current date - myDate = TimeSpan, get total hours and divide in the total hours per year and get exacly the age/months/days...

@Wiktor Zychla 2018-06-27 08:32:36

What about leap years?

@flindeberg 2012-11-23 15:00:31

This is not a direct answer, but more of a philosophical reasoning about the problem at hand from a quasi-scientific point of view.

I would argue that the question does not specify the unit nor culture in which to measure age, most answers seem to assume an integer annual representation. The SI-unit for time is second, ergo the correct generic answer should be (of course assuming normalized DateTime and taking no regard whatsoever to relativistic effects):

var lifeInSeconds = (DateTime.Now.Ticks - then.Ticks)/TickFactor;

In the Christian way of calculating age in years:

var then = ... // Then, in this case the birthday
var now = DateTime.UtcNow;
int age = now.Year - then.Year;
if (now.AddYears(-age) < then) age--;

In finance there is a similar problem when calculating something often referred to as the Day Count Fraction, which roughly is a number of years for a given period. And the age issue is really a time measuring issue.

Example for the actual/actual (counting all days "correctly") convention:

DateTime start, end = .... // Whatever, assume start is before end

double startYearContribution = 1 - (double) start.DayOfYear / (double) (DateTime.IsLeapYear(start.Year) ? 366 : 365);
double endYearContribution = (double)end.DayOfYear / (double)(DateTime.IsLeapYear(end.Year) ? 366 : 365);
double middleContribution = (double) (end.Year - start.Year - 1);

double DCF = startYearContribution + endYearContribution + middleContribution;

Another quite common way to measure time generally is by "serializing" (the dude who named this date convention must seriously have been trippin'):

DateTime start, end = .... // Whatever, assume start is before end
int days = (end - start).Days;

I wonder how long we have to go before a relativistic age in seconds becomes more useful than the rough approximation of earth-around-sun-cycles during one's lifetime so far :) Or in other words, when a period must be given a location or a function representing motion for itself to be valid :)

@Sunny Jangid 2017-10-27 06:43:04

Simple Code

 var birthYear=1993;
 var age = DateTime.Now.AddYears(-birthYear).Year;

@Ahmed Sabry 2015-10-12 13:12:02

public string GetAge(this DateTime birthdate, string ageStrinFormat = null)
{
    var date = DateTime.Now.AddMonths(-birthdate.Month).AddDays(-birthdate.Day);
    return string.Format(ageStrinFormat ?? "{0}/{1}/{2}",
        (date.Year - birthdate.Year), date.Month, date.Day);
}

@Michael Stum 2008-08-01 21:46:12

Another function, not by me but found on the web and refined it a bit:

public static int GetAge(DateTime birthDate)
{
    DateTime n = DateTime.Now; // To avoid a race condition around midnight
    int age = n.Year - birthDate.Year;

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

    return age;
}

Just two things that come into my mind: What about people from countries that do not use the gregorian calendar? DateTime.Now is in the server-specific culture i think. I have absolutely 0 knowledge about actually working with Asian calendars and I do not know if there is an easy way to convert dates between calendars, but just in case you're wondering about those chinese guys from the year 4660 :-)

@webdad3 2016-11-09 22:06:26

This appears to handle different regions (date formats) the best.

@Sean Kearon 2017-07-16 10:39:21

I often count on my fingers. I need to look a calendar to work out when things change. So that's what I'd do in my code:

int AgeNow(DateTime birthday)
{
    return AgeAt(DateTime.Now, birthday);
}

int AgeAt(DateTime now, DateTime birthday)
{
    return AgeAt(now, birthday, CultureInfo.CurrentCulture.Calendar);
}

int AgeAt(DateTime now, DateTime birthday, Calendar calendar)
{
    // My age has increased on the morning of my 
    // birthday even though I was born in the evening.
    now = now.Date;
    birthday = birthday.Date;

    var age = 0;
    if (now <= birthday) return age; // I am zero now if I am to be born tomorrow.

    while (calendar.AddYears(birthday, age + 1) <= now)
    {
        age++;
    }
    return age;
}

Running this through in LinqPad gives this:

PASSED: someone born on 28 February 1964 is age 4 on 28 February 1968
PASSED: someone born on 29 February 1964 is age 3 on 28 February 1968
PASSED: someone born on 31 December 2016 is age 0 on 01 January 2017

Code in LinqPad is here

@ScArcher2 2008-08-15 03:47:29

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;
}

@radarbob 2014-11-19 19:43:01

Horray for yyyymmdd. The 1st database product I used on a Personal Computer (circa 1981) stored dates in this format. Date manipulation of any kind was so much easier.

@Patrik 2015-07-03 12:01:00

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

@numerek 2015-09-03 20:14:30

in your alternate answer, you can avoid integer overflow by subtracting the years then subtract month * 30.5 + day and divide by 366

@GalacticCowboy 2015-09-03 20:23:57

@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

@krvladislav 2016-03-28 08:39:17

It would be better to add a parameter: float.Parse(x, CultureInfo.InvariantCulture) because some locals use comma instead of dot for a delimiter in fractional numbers

@Antonín Lejsek 2017-01-01 02:07:33

DateTime.MaxValue year is 9999, MinValue year is 1, overflow is not possible.

@Jamie Kitson 2018-02-13 09:38:58

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

@Monojit Sarkar 2018-02-25 08:24:56

asking for question for very old post int age = (now - dob) / 10000; why you subtracts by 10000 ?

@LongChalk 2018-06-10 10:57:57

So if someone was born on 20171231, then a day later 20180101 he is 1 year old? I think not.

@Rufus L 2018-06-14 20:36:33

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

@flindeberg 2018-07-03 18:13:51

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

@Rufus L 2018-07-03 19:32:28

@flindeberg Yeah, that's what I was saying to LongChalk...

@flindeberg 2018-07-11 07:11:35

Sorry, I must have cross read somehow

@Lucca Ferri 2018-10-25 11:15:59

I know this is an old answer but I wouldn't make an extension method out of it, it's not the right place to define such logics.

@K1laba 2016-10-22 19:10:42

    private int GetYearDiff(DateTime start, DateTime end)
    {
        int diff = end.Year - start.Year;
        if (end.DayOfYear < start.DayOfYear) { diff -= 1; }
        return diff;
    }
    [Fact]
    public void GetYearDiff_WhenCalls_ShouldReturnCorrectYearDiff()
    {
        //arrange
        var now = DateTime.Now;
        //act
        //assert
        Assert.Equal(24, GetYearDiff(new DateTime(1992, 7, 9), now)); // passed
        Assert.Equal(24, GetYearDiff(new DateTime(1992, now.Month, now.Day), now)); // passed
        Assert.Equal(23, GetYearDiff(new DateTime(1992, 12, 9), now)); // passed
    }

@André Sobreiro 2016-09-29 20:13:16

Wow, I had to give my comment here.. There are so many answers for such a simple

private int CalcularIdade(DateTime dtNascimento)
    {
        var nHoje = Convert.ToInt32(DateTime.Today.ToString("yyyyMMdd"));
        var nAniversario = Convert.ToInt32(dtNascimento.ToString("yyyyMMdd"));

        double diff = (nHoje - nAniversario) / 10000;

        var ret = Convert.ToInt32(Math.Truncate(diff));

        return ret;
    }

Hope it can help someone, at least will make somebody think.. :)

@Vinicius Gonçalves 2017-11-08 19:24:41

It should be written in English.

@xenedia 2016-06-30 11:24:56

SQL version:

declare @dd smalldatetime = '1980-04-01'
declare @age int = YEAR(GETDATE())-YEAR(@dd)
if (@dd> DATEADD(YYYY, [email protected], GETDATE())) set @age = @age -1

print @age  

@John_J 2016-05-04 08:29:20

=== Common Saying (from months to years old) ===

If you just for common use, here is the code as your information:

DateTime today = DateTime.Today;
DateTime bday = DateTime.Parse("2016-2-14");
int age = today.Year - bday.Year;
var unit = "";

if (bday > today.AddYears(-age))
{
    age--;
}
if (age == 0)   // Under one year old
{
    age = today.Month - bday.Month;

    age = age <= 0 ? (12 + age) : age;  // The next year before birthday

    age = today.Day - bday.Day >= 0 ? age : --age;  // Before the birthday.day

    unit = "month";
}
else {
    unit = "year";
}

if (age > 1)
{
    unit = unit + "s";
}

The test result as below:

The birthday: 2016-2-14

2016-2-15 =>  age=0, unit=month;
2016-5-13 =>  age=2, unit=months;
2016-5-14 =>  age=3, unit=months; 
2016-6-13 =>  age=3, unit=months; 
2016-6-15 =>  age=4, unit=months; 
2017-1-13 =>  age=10, unit=months; 
2017-1-14 =>  age=11, unit=months; 
2017-2-13 =>  age=11, unit=months; 
2017-2-14 =>  age=1, unit=year; 
2017-2-15 =>  age=1, unit=year; 
2017-3-13 =>  age=1, unit=year;
2018-1-13 =>  age=1, unit=year; 
2018-1-14 =>  age=1, unit=year; 
2018-2-13 =>  age=1, unit=year; 
2018-2-14 =>  age=2, unit=years; 

@CathalMF 2016-04-27 14:58:06

This is the easiest way to answer this in a single line.

DateTime Dob = DateTime.Parse("1985-04-24");

int Age = DateTime.MinValue.AddDays(DateTime.Now.Subtract(Dob).TotalHours/24).Year - 1;

This also works for leap years.

@Aman 2016-12-08 14:13:52

your answer is wrong by one day, it will give the birthday a day before

@rockXrock 2012-11-30 12:13:21

Do we need to consider people who is smaller than 1 year? as Chinese culture, we describe small babies' age as 2 months or 4 weeks.

Below is my implementation, it is not as simple as what I imagined, especially to deal with date like 2/28.

public static string HowOld(DateTime birthday, DateTime now)
{
    if (now < birthday)
        throw new ArgumentOutOfRangeException("birthday must be less than now.");

    TimeSpan diff = now - birthday;
    int diffDays = (int)diff.TotalDays;

    if (diffDays > 7)//year, month and week
    {
        int age = now.Year - birthday.Year;

        if (birthday > now.AddYears(-age))
            age--;

        if (age > 0)
        {
            return age + (age > 1 ? " years" : " year");
        }
        else
        {// month and week
            DateTime d = birthday;
            int diffMonth = 1;

            while (d.AddMonths(diffMonth) <= now)
            {
                diffMonth++;
            }

            age = diffMonth-1;

            if (age == 1 && d.Day > now.Day)
                age--;

            if (age > 0)
            {
                return age + (age > 1 ? " months" : " month");
            }
            else
            {
                age = diffDays / 7;
                return age + (age > 1 ? " weeks" : " week");
            }
        }
    }
    else if (diffDays > 0)
    {
        int age = diffDays;
        return age + (age > 1 ? " days" : " day");
    }
    else
    {
        int age = diffDays;
        return "just born";
    }
}

This implementation has passed below test cases.

[TestMethod]
public void TestAge()
{
    string age = HowOld(new DateTime(2011, 1, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 year", age);

    age = HowOld(new DateTime(2011, 11, 30), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 year", age);

    age = HowOld(new DateTime(2001, 1, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("11 years", age);

    age = HowOld(new DateTime(2012, 1, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("10 months", age);

    age = HowOld(new DateTime(2011, 12, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("11 months", age);

    age = HowOld(new DateTime(2012, 10, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 month", age);

    age = HowOld(new DateTime(2008, 2, 28), new DateTime(2009, 2, 28));
    Assert.AreEqual("1 year", age);

    age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 2, 28));
    Assert.AreEqual("11 months", age);

    age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 3, 28));
    Assert.AreEqual("1 year", age);

    age = HowOld(new DateTime(2009, 1, 28), new DateTime(2009, 2, 28));
    Assert.AreEqual("1 month", age);

    age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1));
    Assert.AreEqual("1 month", age);

    // NOTE.
    // new DateTime(2008, 1, 31).AddMonths(1) == new DateTime(2009, 2, 28);
    // new DateTime(2008, 1, 28).AddMonths(1) == new DateTime(2009, 2, 28);
    age = HowOld(new DateTime(2009, 1, 31), new DateTime(2009, 2, 28));
    Assert.AreEqual("4 weeks", age);

    age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 2, 28));
    Assert.AreEqual("3 weeks", age);

    age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1));
    Assert.AreEqual("1 month", age);

    age = HowOld(new DateTime(2012, 11, 5), new DateTime(2012, 11, 30));
    Assert.AreEqual("3 weeks", age);

    age = HowOld(new DateTime(2012, 11, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("4 weeks", age);

    age = HowOld(new DateTime(2012, 11, 20), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 week", age);

    age = HowOld(new DateTime(2012, 11, 25), new DateTime(2012, 11, 30));
    Assert.AreEqual("5 days", age);

    age = HowOld(new DateTime(2012, 11, 29), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 day", age);

    age = HowOld(new DateTime(2012, 11, 30), new DateTime(2012, 11, 30));
    Assert.AreEqual("just born", age);

    age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 2, 28));
    Assert.AreEqual("8 years", age);

    age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 3, 1));
    Assert.AreEqual("9 years", age);

    Exception e = null;

    try
    {
        age = HowOld(new DateTime(2012, 12, 1), new DateTime(2012, 11, 30));
    }
    catch (ArgumentOutOfRangeException ex)
    {
        e = ex;
    }

    Assert.IsTrue(e != null);
}

Hope it's helpful.

@Doron 2011-03-08 07:25:02

How about this solution?

static string CalcAge(DateTime birthDay)
{
    DateTime currentDate = DateTime.Now;         
    int approximateAge = currentDate.Year - birthDay.Year;
    int daysToNextBirthDay = (birthDay.Month * 30 + birthDay.Day) - 
        (currentDate.Month * 30 + currentDate.Day) ;

    if (approximateAge == 0 || approximateAge == 1)
    {                
        int month =  Math.Abs(daysToNextBirthDay / 30);
        int days = Math.Abs(daysToNextBirthDay % 30);

        if (month == 0)
            return "Your age is: " + daysToNextBirthDay + " days";

        return "Your age is: " + month + " months and " + days + " days"; ;
    }

    if (daysToNextBirthDay > 0)
        return "Your age is: " + --approximateAge + " Years";

    return "Your age is: " + approximateAge + " Years"; ;
}

@AEMLoviji 2010-09-06 14:09:01

private int GetAge(int _year, int _month, int _day
{
    DateTime yourBirthDate= new DateTime(_year, _month, _day);

    DateTime todaysDateTime = DateTime.Today;
    int noOfYears = todaysDateTime.Year - yourBirthDate.Year;

    if (DateTime.Now.Month < yourBirthDate.Month ||
        (DateTime.Now.Month == yourBirthDate.Month && DateTime.Now.Day < yourBirthDate.Day))
    {
        noOfYears--;
    }

    return  noOfYears;
}

Related Questions

Sponsored Content

38 Answered Questions

[SOLVED] How do you get a timestamp in JavaScript?

61 Answered Questions

[SOLVED] What is the difference between String and string in C#?

27 Answered Questions

[SOLVED] How do I enumerate an enum in C#?

9 Answered Questions

[SOLVED] What are the correct version numbers for C#?

35 Answered Questions

[SOLVED] Determine Whether Two Date Ranges Overlap

24 Answered Questions

[SOLVED] Cast int to enum in C#

  • 2008-08-27 03:58:21
  • lomaxx
  • 1171890 View
  • 2845 Score
  • 24 Answer
  • Tags:   c# enums casting

42 Answered Questions

[SOLVED] How to create Excel (.XLS and .XLSX) file in C# without installing Ms Office?

  • 2008-09-29 22:30:28
  • mistrmark
  • 996924 View
  • 1729 Score
  • 42 Answer
  • Tags:   c# .net excel file-io

38 Answered Questions

12 Answered Questions

[SOLVED] Why is it important to override GetHashCode when Equals method is overridden?

  • 2008-12-16 13:41:18
  • David Basarab
  • 334754 View
  • 1303 Score
  • 12 Answer
  • Tags:   c# override hashcode

36 Answered Questions

[SOLVED] Calculate relative time in C#

Sponsored Content