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


当前回答

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

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

其他回答

为什么不能简化为检查出生日期?

第一行(var year=end.year-start.year-1;):假设出生日期尚未发生在结束年份。然后检查月份和日期,看看是否发生了;再增加一年。

对闰年情景没有特殊处理。如果不是闰年,你不能创建一个日期(2月29日)作为结束日期,所以如果结束日期是3月1日,而不是28日,生日庆祝活动将被计算在内。下面的函数将将此场景作为普通日期进行描述。

    static int Get_Age(DateTime start, DateTime end)
    {
        var year = end.Year - start.Year - 1;
        if (end.Month < start.Month)
            return year;
        else if (end.Month == start.Month)
        {
            if (end.Day >= start.Day)
                return ++year;
            return year;
        }
        else
            return ++year;
    }

    static void Test_Get_Age()
    {
        var start = new DateTime(2008, 4, 10); // b-date, leap year BTY
        var end = new DateTime(2023, 2, 1); // end date is before the b-date
        var result1 = Get_Age(start, end);
        var success1 = result1 == 14; // true

        end = new DateTime(2023, 4, 10); // end date is on the b-date
        var result2 = Get_Age(start, end);
        var success2 = result2 == 15; // true

        end = new DateTime(2023, 6, 22); // end date is after the b-date
        var result3 = Get_Age(start, end);
        var success3 = result3 == 15; // true

        start = new DateTime(2008, 2, 29); // b-date is on feb 29
        end = new DateTime(2023, 2, 28); // end date is before the b-date
        var result4 = Get_Age(start, end);
        var success4 = result4 == 14; // true

        end = new DateTime(2020, 2, 29); // end date is on the b-date, on another leap year
        var result5 = Get_Age(start, end);
        var success5 = result5 == 12; // true
    }

这可能会起作用:

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

这里有一个小的C#代码示例,我总结了一下,请注意边缘情况,特别是闰年,并不是所有上述解决方案都考虑到这些情况。将答案推出来作为DateTime可能会导致问题,因为你可能会在一个特定的月份中投入太多的时间,例如2月的30天。

public string 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 = 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++;
    }

    return "Years: " + years + " Months: " + months + " Days: " + days;
}

我花了一些时间研究这个问题,并用这个来计算某人的年龄,以年、月和日为单位。我已经针对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++;
    }

}

我的建议

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

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