给定代表某人生日的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;
其他回答
这个经典问题值得野田时间来解决。
static int GetAge(LocalDate dateOfBirth)
{
Instant now = SystemClock.Instance.Now;
// The target time zone is important.
// It should align with the *current physical location* of the person
// you are talking about. When the whereabouts of that person are unknown,
// then you use the time zone of the person who is *asking* for the age.
// The time zone of birth is irrelevant!
DateTimeZone zone = DateTimeZoneProviders.Tzdb["America/New_York"];
LocalDate today = now.InZone(zone).Date;
Period period = Period.Between(dateOfBirth, today, PeriodUnits.Years);
return (int) period.Years;
}
用法:
LocalDate dateOfBirth = new LocalDate(1976, 8, 27);
int age = GetAge(dateOfBirth);
您可能还对以下改进感兴趣:
将时钟作为IClock传递,而不是使用SystemClock.Instance,将提高可测试性。目标时区可能会更改,因此您也需要DateTimeZone参数。
另请参阅我关于这个主题的博客文章:处理生日和其他周年纪念日
为什么不能简化为检查出生日期?
第一行(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
}
这里有一个非常简单且易于遵循的示例。
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;
}
这是一种奇怪的方法,但如果您将日期设置为yyyymmdd,并从当前日期中减去出生日期,然后删除您获得的年龄的最后4位数字:)
我不知道C#,但我相信这在任何语言中都适用。
20080814 - 19800703 = 280111
删除最后4位=28。
C#代码:
int now = int.Parse(DateTime.Now.ToString("yyyyMMdd"));
int dob = int.Parse(dateOfBirth.ToString("yyyyMMdd"));
int age = (now - dob) / 10000;
或者,也可以不进行扩展方法形式的所有类型转换。忽略错误检查:
public static Int32 GetAge(this DateTime dateOfBirth)
{
var today = DateTime.Today;
var a = (today.Year * 100 + today.Month) * 100 + today.Day;
var b = (dateOfBirth.Year * 100 + dateOfBirth.Month) * 100 + dateOfBirth.Day;
return (a - b) / 10000;
}
保持简单(可能是愚蠢的:)。
DateTime birth = new DateTime(1975, 09, 27, 01, 00, 00, 00);
TimeSpan ts = DateTime.Now - birth;
Console.WriteLine("You are approximately " + ts.TotalSeconds.ToString() + " seconds old.");
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 解析日期字符串并更改格式
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?