给定代表某人生日的DateTime,我如何计算他们的年龄(以年为单位)?
当前回答
这个经典问题值得野田时间来解决。
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参数。
另请参阅我关于这个主题的博客文章:处理生日和其他周年纪念日
其他回答
==常见说法(从几个月到几岁)===
如果您只是为了通用,以下是代码作为您的信息:
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;
要使用最近的年龄计算年龄:
var ts = DateTime.Now - new DateTime(1988, 3, 19);
var age = Math.Round(ts.Days / 365.0);
只是因为我认为最重要的答案不是那么明确:
public static int GetAgeByLoop(DateTime birthday)
{
var age = -1;
for (var date = birthday; date < DateTime.Today; date = date.AddYears(1))
{
age++;
}
return age;
}
为了计算一个人的年龄,
DateTime dateOfBirth;
int ageInYears = DateTime.Now.Year - dateOfBirth.Year;
if (dateOfBirth > today.AddYears(-ageInYears )) ageInYears --;
这是一个非常适合我的功能。没有计算,非常简单。
public static string ToAge(this DateTime dob, DateTime? toDate = null)
{
if (!toDate.HasValue)
toDate = DateTime.Now;
var now = toDate.Value;
if (now.CompareTo(dob) < 0)
return "Future date";
int years = now.Year - dob.Year;
int months = now.Month - dob.Month;
int days = now.Day - dob.Day;
if (days < 0)
{
months--;
days = DateTime.DaysInMonth(dob.Year, dob.Month) - dob.Day + now.Day;
}
if (months < 0)
{
years--;
months = 12 + months;
}
return string.Format("{0} year(s), {1} month(s), {2} days(s)",
years,
months,
days);
}
这里是一个单元测试:
[Test]
public void ToAgeTests()
{
var date = new DateTime(2000, 1, 1);
Assert.AreEqual("0 year(s), 0 month(s), 1 days(s)", new DateTime(1999, 12, 31).ToAge(date));
Assert.AreEqual("0 year(s), 0 month(s), 0 days(s)", new DateTime(2000, 1, 1).ToAge(date));
Assert.AreEqual("1 year(s), 0 month(s), 0 days(s)", new DateTime(1999, 1, 1).ToAge(date));
Assert.AreEqual("0 year(s), 11 month(s), 0 days(s)", new DateTime(1999, 2, 1).ToAge(date));
Assert.AreEqual("0 year(s), 10 month(s), 25 days(s)", new DateTime(1999, 2, 4).ToAge(date));
Assert.AreEqual("0 year(s), 10 month(s), 1 days(s)", new DateTime(1999, 2, 28).ToAge(date));
date = new DateTime(2000, 2, 15);
Assert.AreEqual("0 year(s), 0 month(s), 28 days(s)", new DateTime(2000, 1, 18).ToAge(date));
}
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制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?