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


当前回答

看看这个:

TimeSpan ts = DateTime.Now.Subtract(Birthdate);
age = (byte)(ts.TotalDays / 365.25);

其他回答

下面是一个测试片段:

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

这里有一些方法:

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

==常见说法(从几个月到几岁)===

如果您只是为了通用,以下是代码作为您的信息:

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

我想添加希伯来文日历计算(或其他系统。全球化日历可以以相同的方式使用),使用此线程中的重写函数:

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

我找到的最简单的方法就是这样。它适用于美国和西欧地区。无法与其他地区通话,尤其是中国这样的地方。在最初计算年龄后,最多可额外进行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;
}

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

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

这可能会起作用:

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