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


当前回答

我使用ScArcher2的解决方案来精确计算人的年龄,但我需要进一步计算他们的月和日以及年。

    public static Dictionary<string,int> CurrentAgeInYearsMonthsDays(DateTime? ndtBirthDate, DateTime? ndtReferralDate)
    {
        //----------------------------------------------------------------------
        // Can't determine age if we don't have a dates.
        //----------------------------------------------------------------------
        if (ndtBirthDate == null) return null;
        if (ndtReferralDate == null) return null;

        DateTime dtBirthDate = Convert.ToDateTime(ndtBirthDate);
        DateTime dtReferralDate = Convert.ToDateTime(ndtReferralDate);

        //----------------------------------------------------------------------
        // Create our Variables
        //----------------------------------------------------------------------
        Dictionary<string, int> dYMD = new Dictionary<string,int>();
        int iNowDate, iBirthDate, iYears, iMonths, iDays;
        string sDif = "";

        //----------------------------------------------------------------------
        // Store off current date/time and DOB into local variables
        //---------------------------------------------------------------------- 
        iNowDate = int.Parse(dtReferralDate.ToString("yyyyMMdd"));
        iBirthDate = int.Parse(dtBirthDate.ToString("yyyyMMdd"));

        //----------------------------------------------------------------------
        // Calculate Years
        //----------------------------------------------------------------------
        sDif = (iNowDate - iBirthDate).ToString();
        iYears = int.Parse(sDif.Substring(0, sDif.Length - 4));

        //----------------------------------------------------------------------
        // Store Years in Return Value
        //----------------------------------------------------------------------
        dYMD.Add("Years", iYears);

        //----------------------------------------------------------------------
        // Calculate Months
        //----------------------------------------------------------------------
        if (dtBirthDate.Month > dtReferralDate.Month)
            iMonths = 12 - dtBirthDate.Month + dtReferralDate.Month - 1;
        else
            iMonths = dtBirthDate.Month - dtReferralDate.Month;

        //----------------------------------------------------------------------
        // Store Months in Return Value
        //----------------------------------------------------------------------
        dYMD.Add("Months", iMonths);

        //----------------------------------------------------------------------
        // Calculate Remaining Days
        //----------------------------------------------------------------------
        if (dtBirthDate.Day > dtReferralDate.Day)
            //Logic: Figure out the days in month previous to the current month, or the admitted month.
            //       Subtract the birthday from the total days which will give us how many days the person has lived since their birthdate day the previous month.
            //       then take the referral date and simply add the number of days the person has lived this month.

            //If referral date is january, we need to go back to the following year's December to get the days in that month.
            if (dtReferralDate.Month == 1)
                iDays = DateTime.DaysInMonth(dtReferralDate.Year - 1, 12) - dtBirthDate.Day + dtReferralDate.Day;       
            else
                iDays = DateTime.DaysInMonth(dtReferralDate.Year, dtReferralDate.Month - 1) - dtBirthDate.Day + dtReferralDate.Day;       
        else
            iDays = dtReferralDate.Day - dtBirthDate.Day;             

        //----------------------------------------------------------------------
        // Store Days in Return Value
        //----------------------------------------------------------------------
        dYMD.Add("Days", iDays);

        return dYMD;
}

其他回答

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

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

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; 

一句话的回答:

DateTime dateOfBirth = Convert.ToDateTime("01/16/1990");
var age = ((DateTime.Now - dateOfBirth).Days) / 365;

我的建议

int age = (int) ((DateTime.Now - bday).TotalDays/365.242199);

这一年似乎在正确的日期发生了变化。(我在107岁之前进行了现场测试。)

这里有一个非常简单且易于遵循的示例。

private int CalculateAge()
{
//get birthdate
   DateTime dtBirth = Convert.ToDateTime(BirthDatePicker.Value);
   int byear = dtBirth.Year;
   int bmonth = dtBirth.Month;
   int bday = dtBirth.Day;
   DateTime dtToday = DateTime.Now;
   int tYear = dtToday.Year;
   int tmonth = dtToday.Month;
   int tday = dtToday.Day;
   int age = tYear - byear;
   if (bmonth < tmonth)
       age--;
   else if (bmonth == tmonth && bday>tday)
   {
       age--;
   }
return age;
}

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

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

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