In C#, how do I calculate someone's age based on a DateTime type birthday?

后端 未结 30 2213
名媛妹妹
名媛妹妹 2020-11-21 05:14

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

30条回答
  •  無奈伤痛
    2020-11-21 05: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.

提交回复
热议问题