给定代表某人生日的DateTime,我如何计算他们的年龄(以年为单位)?
当前回答
对此的简单答案是应用AddYears,如下所示,因为这是唯一一种将年份添加到闰年2月29日的本地方法,并获得普通年份2月28日的正确结果。
有些人认为3月1日是勒普林斯的生日,但.Net和任何官方规则都不支持这一点,也没有常见的逻辑解释为什么一些出生在2月的人应该在另一个月拥有75%的生日。
此外,Age方法可以作为DateTime的扩展添加。由此,您可以以最简单的方式获得年龄:
列表项目
int age=出生日期.age();
public static class DateTimeExtensions
{
/// <summary>
/// Calculates the age in years of the current System.DateTime object today.
/// </summary>
/// <param name="birthDate">The date of birth</param>
/// <returns>Age in years today. 0 is returned for a future date of birth.</returns>
public static int Age(this DateTime birthDate)
{
return Age(birthDate, DateTime.Today);
}
/// <summary>
/// Calculates the age in years of the current System.DateTime object on a later date.
/// </summary>
/// <param name="birthDate">The date of birth</param>
/// <param name="laterDate">The date on which to calculate the age.</param>
/// <returns>Age in years on a later day. 0 is returned as minimum.</returns>
public static int Age(this DateTime birthDate, DateTime laterDate)
{
int age;
age = laterDate.Year - birthDate.Year;
if (age > 0)
{
age -= Convert.ToInt32(laterDate.Date < birthDate.Date.AddYears(age));
}
else
{
age = 0;
}
return age;
}
}
现在,运行此测试:
class Program
{
static void Main(string[] args)
{
RunTest();
}
private static void RunTest()
{
DateTime birthDate = new DateTime(2000, 2, 28);
DateTime laterDate = new DateTime(2011, 2, 27);
string iso = "yyyy-MM-dd";
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Console.WriteLine("Birth date: " + birthDate.AddDays(i).ToString(iso) + " Later date: " + laterDate.AddDays(j).ToString(iso) + " Age: " + birthDate.AddDays(i).Age(laterDate.AddDays(j)).ToString());
}
}
Console.ReadKey();
}
}
关键日期示例如下:
出生日期:2000-02-29出生日期:2011-02-28年龄:11
输出:
{
Birth date: 2000-02-28 Later date: 2011-02-27 Age: 10
Birth date: 2000-02-28 Later date: 2011-02-28 Age: 11
Birth date: 2000-02-28 Later date: 2011-03-01 Age: 11
Birth date: 2000-02-29 Later date: 2011-02-27 Age: 10
Birth date: 2000-02-29 Later date: 2011-02-28 Age: 11
Birth date: 2000-02-29 Later date: 2011-03-01 Age: 11
Birth date: 2000-03-01 Later date: 2011-02-27 Age: 10
Birth date: 2000-03-01 Later date: 2011-02-28 Age: 10
Birth date: 2000-03-01 Later date: 2011-03-01 Age: 11
}
2012年2月28日晚些时候:
{
Birth date: 2000-02-28 Later date: 2012-02-28 Age: 12
Birth date: 2000-02-28 Later date: 2012-02-29 Age: 12
Birth date: 2000-02-28 Later date: 2012-03-01 Age: 12
Birth date: 2000-02-29 Later date: 2012-02-28 Age: 11
Birth date: 2000-02-29 Later date: 2012-02-29 Age: 12
Birth date: 2000-02-29 Later date: 2012-03-01 Age: 12
Birth date: 2000-03-01 Later date: 2012-02-28 Age: 11
Birth date: 2000-03-01 Later date: 2012-02-29 Age: 11
Birth date: 2000-03-01 Later date: 2012-03-01 Age: 12
}
其他回答
为什么不能简化为检查出生日期?
第一行(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
}
这个解决方案怎么样?
static string CalcAge(DateTime birthDay)
{
DateTime currentDate = DateTime.Now;
int approximateAge = currentDate.Year - birthDay.Year;
int daysToNextBirthDay = (birthDay.Month * 30 + birthDay.Day) -
(currentDate.Month * 30 + currentDate.Day) ;
if (approximateAge == 0 || approximateAge == 1)
{
int month = Math.Abs(daysToNextBirthDay / 30);
int days = Math.Abs(daysToNextBirthDay % 30);
if (month == 0)
return "Your age is: " + daysToNextBirthDay + " days";
return "Your age is: " + month + " months and " + days + " days"; ;
}
if (daysToNextBirthDay > 0)
return "Your age is: " + --approximateAge + " Years";
return "Your age is: " + approximateAge + " Years"; ;
}
另一个功能,不是我做的,而是在网上找到的,并做了一些改进:
public static int GetAge(DateTime birthDate)
{
DateTime n = DateTime.Now; // To avoid a race condition around midnight
int age = n.Year - birthDate.Year;
if (n.Month < birthDate.Month || (n.Month == birthDate.Month && n.Day < birthDate.Day))
age--;
return age;
}
我只想到了两件事:来自不使用公历的国家的人呢?DateTime。我认为现在是服务器特定的文化。我对实际使用亚洲日历一无所知,我不知道是否有一种简单的方法来转换日历之间的日期,但以防万一,你想知道4660年的中国人:-)
简单易懂的解决方案。
// Save today's date.
var today = DateTime.Today;
// Calculate the age.
var age = today.Year - birthdate.Year;
// Go back to the year in which the person was born in case of a leap year
if (birthdate.Date > today.AddYears(-age)) age--;
然而,这假设你在寻找西方的时代观念,而不是使用东亚的推算法。
下面是一个测试片段:
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;
}
推荐文章
- dynamic (c# 4)和var之间的区别是什么?
- Visual Studio: ContextSwitchDeadlock
- Sql Server字符串到日期的转换
- 返回文件在ASP。Net Core Web API
- 自定义HttpClient请求头
- 如果我使用OWIN Startup.cs类并将所有配置移动到那里,我是否需要一个Global.asax.cs文件?
- VS2013外部构建错误"error MSB4019: The imported project <path> was not found"
- 从另一个列表id中排序一个列表
- 等待一个无效的异步方法
- 无法加载文件或程序集…参数不正确
- c#中枚举中的方法
- 如何从字符串中删除新的行字符?
- 如何设置一个默认值与Html.TextBoxFor?
- 检查属性是否有属性
- 格式化XML字符串以打印友好的XML字符串