给定代表某人生日的DateTime,我如何计算他们的年龄(以年为单位)?


当前回答

        var EndDate = new DateTime(2022, 4, 21);

        var StartDate = new DateTime(1986, 4, 25);

        Int32 Months = EndDate.Month - StartDate.Month;

        Int32 Years = EndDate.Year - StartDate.Year;

        Int32 Days = EndDate.Day - StartDate.Day;

        if (Days < 0)
        {
            Months = Months - 1;
        }

        if (Months < 0)
        {
            Years = Years - 1;

            Months = Months + 12;
        }
        
        string Ages = Years.ToString() + " Year(s) " + Months.ToString() + " Month(s) ";

其他回答

这里有一个单行线:

int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1;

我找到的最简单的方法就是这样。它适用于美国和西欧地区。无法与其他地区通话,尤其是中国这样的地方。在最初计算年龄后,最多可额外进行4次比较。

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

我仔细查看了答案,发现没有人提及闰日出生的监管/法律影响。例如,根据维基百科,如果你在2月29日出生在不同的司法管辖区,你的非闰年生日会有所不同:

在英国和香港:这是一年中的第几天,所以第二天,3月1日是你的生日。在新西兰:这是前一天,2月28日用于驾驶执照,3月1日用于其他目的。台湾:今天是2月28日。

据我所知,在美国,法规对此事保持沉默,这取决于普通法以及各个监管机构如何在其法规中定义事物。

为此,需要改进:

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

需要注意的是,该代码假设:

西方(欧洲)对年龄的推算,以及一种日历,如公历,在月底插入一个闰日。

我花了一些时间研究这个问题,并用这个来计算某人的年龄,以年、月和日为单位。我已经针对2月29日的问题和闰年进行了测试,它似乎奏效了,我希望得到任何反馈:

public void LoopAge(DateTime myDOB, DateTime FutureDate)
{
    int years = 0;
    int months = 0;
    int days = 0;

    DateTime tmpMyDOB = new DateTime(myDOB.Year, myDOB.Month, 1);

    DateTime tmpFutureDate = new DateTime(FutureDate.Year, FutureDate.Month, 1);

    while (tmpMyDOB.AddYears(years).AddMonths(months) < tmpFutureDate)
    {
        months++;

        if (months > 12)
        {
            years++;
            months = months - 12;
        }
    }

    if (FutureDate.Day >= myDOB.Day)
    {
        days = days + FutureDate.Day - myDOB.Day;
    }
    else
    {
        months--;

        if (months < 0)
        {
            years--;
            months = months + 12;
        }

        days +=
            DateTime.DaysInMonth(
                FutureDate.AddMonths(-1).Year, FutureDate.AddMonths(-1).Month
            ) + FutureDate.Day - myDOB.Day;

    }

    //add an extra day if the dob is a leap day
    if (DateTime.IsLeapYear(myDOB.Year) && myDOB.Month == 2 && myDOB.Day == 29)
    {
        //but only if the future date is less than 1st March
        if (FutureDate >= new DateTime(FutureDate.Year, 3, 1))
            days++;
    }

}

SQL版本:

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

print @age  
TimeSpan diff = DateTime.Now - birthdayDateTime;
string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff);

我不知道你到底希望它返回给你多少,所以我只是做了一个可读的字符串。