给定代表某人生日的DateTime,我如何计算他们的年龄(以年为单位)?
当前回答
==常见说法(从几个月到几岁)===
如果您只是为了通用,以下是代码作为您的信息:
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 dob = new DateTime(1991, 3, 4);
DateTime now = DateTime.Now;
int dobDay = dob.Day, dobMonth = dob.Month;
int add = -1;
if (dobMonth < now.Month)
{
add = 0;
}
else if (dobMonth == now.Month)
{
if(dobDay <= now.Day)
{
add = 0;
}
else
{
add = -1;
}
}
else
{
add = -1;
}
int age = now.Year - dob.Year + add;
我认为TimeSpan包含了我们所需要的一切,而不必求助于365.25(或任何其他近似值)。扩展Aug的示例:
DateTime myBD = new DateTime(1980, 10, 10);
TimeSpan difference = DateTime.Now.Subtract(myBD);
textBox1.Text = difference.Years + " years " + difference.Months + " Months " + difference.Days + " days";
这是我们在这里使用的版本。它有效,而且相当简单。这与Jeff的想法相同,但我认为它更清晰一点,因为它分离了减法的逻辑,所以更容易理解。
public static int GetAge(this DateTime dateOfBirth, DateTime dateAsAt)
{
return dateAsAt.Year - dateOfBirth.Year - (dateOfBirth.DayOfYear < dateAsAt.DayOfYear ? 0 : 1);
}
如果你认为这类事情不清楚,你可以扩展三元运算符使其更清晰。
显然,这是作为DateTime上的一个扩展方法完成的,但很明显,您可以抓取一行代码来完成工作并将其放在任何位置。这里我们有另一个传入DateTime的Extension方法重载。
还有一个答案:
public static int AgeInYears(DateTime birthday, DateTime today)
{
return ((today.Year - birthday.Year) * 372 + (today.Month - birthday.Month) * 31 + (today.Day - birthday.Day)) / 372;
}
这已经过广泛的单元测试。它看起来确实有点“神奇”。数字372是如果每个月有31天,一年中会有多少天。
其工作原理的解释(此处省略)如下:
让我们设置Yn=DateTime.Now.Year,Yb=生日.Year,Mn=DateTime.Now.Month,Mb=生日.Month、Dn=DateTime.Now.Day,Db=生日.Day年龄=Yn-Yb+(31*(Mn-Mb)+(Dn-Db))/372我们知道,如果日期已经到达,我们需要的是Yn-Yb,如果日期尚未到达,则需要Yn-Yb-1。a) 如果Mn<Mb,我们有-341<=31*(Mn-Mb)<=-31和-30<=Dn-Db<=30-371<=31*(锰-Mb)+(Dn-Db)<=-1带整数除法(31*(Mn-Mb)+(Dn-Db))/372=-1b) 如果Mn=Mb和Dn<Db,则我们有31*(Mn-Mb)=0和-30<=Dn Db<=-1再次使用整数除法(31*(Mn-Mb)+(Dn-Db))/372=-1c) 如果Mn>Mb,我们有31<=31*(Mn-Mb)<=341和-30<=Dn-Db<=301<=31*(Mn-Mb)+(Dn-Db)<=371带整数除法(31*(Mn-Mb)+(Dn-Db))/372=0d) 如果Mn=Mb且Dn>Db,则我们有31*(Mn-Mb)=0且1<=Dn Db<=30再次使用整数除法(31*(Mn-Mb)+(Dn-Db))/372=0e) 如果Mn=Mb,Dn=Db,我们有31*(Mn-Mb)+Dn Db=0因此(31*(Mn-Mb)+(Dn-Db))/372=0
我花了一些时间研究这个问题,并用这个来计算某人的年龄,以年、月和日为单位。我已经针对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++;
}
}