给定代表某人生日的DateTime,我如何计算他们的年龄(以年为单位)?
当前回答
我花了一些时间研究这个问题,并用这个来计算某人的年龄,以年、月和日为单位。我已经针对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++;
}
}
其他回答
简单易读,方法互补
public static int getAge(DateTime birthDate)
{
var today = DateTime.Today;
var age = today.Year - birthDate.Year;
var monthDiff = today.Month - birthDate.Month;
var dayDiff = today.Day - birthDate.Day;
if (dayDiff < 0)
{
monthDiff--;
}
if (monthDiff < 0)
{
age--;
}
return age;
}
这里有一个小的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;
}
我找到的最简单的方法就是这样。它适用于美国和西欧地区。无法与其他地区通话,尤其是中国这样的地方。在最初计算年龄后,最多可额外进行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;
}
因为闰年和所有事情,我知道的最好的方法是:
DateTime birthDate = new DateTime(2000,3,1);
int age = (int)Math.Floor((DateTime.Now - birthDate).TotalDays / 365.25D);