给定代表某人生日的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
}
其他回答
private int GetYearDiff(DateTime start, DateTime end)
{
int diff = end.Year - start.Year;
if (end.DayOfYear < start.DayOfYear) { diff -= 1; }
return diff;
}
[Fact]
public void GetYearDiff_WhenCalls_ShouldReturnCorrectYearDiff()
{
//arrange
var now = DateTime.Now;
//act
//assert
Assert.Equal(24, GetYearDiff(new DateTime(1992, 7, 9), now)); // passed
Assert.Equal(24, GetYearDiff(new DateTime(1992, now.Month, now.Day), now)); // passed
Assert.Equal(23, GetYearDiff(new DateTime(1992, 12, 9), now)); // passed
}
这可能会起作用:
public override bool IsValid(DateTime value)
{
_dateOfBirth = value;
var yearsOld = (double) (DateTime.Now.Subtract(_dateOfBirth).TotalDays/365);
if (yearsOld > 18)
return true;
return false;
}
2需要解决的主要问题有:
1.计算准确年龄-以年、月、日等为单位。
2.计算人们普遍认为的年龄——人们通常不关心自己到底多大,他们只关心自己当年的生日是什么时候。
1的解决方案显而易见:
DateTime birth = DateTime.Parse("1.1.2000");
DateTime today = DateTime.Today; //we usually don't care about birth time
TimeSpan age = today - birth; //.NET FCL should guarantee this as precise
double ageInDays = age.TotalDays; //total number of days ... also precise
double daysInYear = 365.2425; //statistical value for 400 years
double ageInYears = ageInDays / daysInYear; //can be shifted ... not so precise
2的解决方案在确定总年龄时并不那么精确,但人们认为它是精确的。当人们“手动”计算年龄时,通常也会使用它:
DateTime birth = DateTime.Parse("1.1.2000");
DateTime today = DateTime.Today;
int age = today.Year - birth.Year; //people perceive their age in years
if (today.Month < birth.Month ||
((today.Month == birth.Month) && (today.Day < birth.Day)))
{
age--; //birthday in current year not yet reached, we are 1 year younger ;)
//+ no birthday for 29.2. guys ... sorry, just wrong date for birth
}
注释2.:
这是我的首选解决方案我们不能使用DateTime.DayOfYear或TimeSpans,因为它们会在闰年中改变天数为了可读性,我只增加了几行
还有一个提示。。。我将为它创建两个静态重载方法,一个用于通用,另一个用于使用友好:
public static int GetAge(DateTime bithDay, DateTime today)
{
//chosen solution method body
}
public static int GetAge(DateTime birthDay)
{
return GetAge(birthDay, DateTime.Now);
}
==常见说法(从几个月到几岁)===
如果您只是为了通用,以下是代码作为您的信息:
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;
我创建了一个Age结构,如下所示:
public struct Age : IEquatable<Age>, IComparable<Age>
{
private readonly int _years;
private readonly int _months;
private readonly int _days;
public int Years { get { return _years; } }
public int Months { get { return _months; } }
public int Days { get { return _days; } }
public Age( int years, int months, int days ) : this()
{
_years = years;
_months = months;
_days = days;
}
public static Age CalculateAge( DateTime dateOfBirth, DateTime date )
{
// Here is some logic that ressembles Mike's solution, although it
// also takes into account months & days.
// Ommitted for brevity.
return new Age (years, months, days);
}
// Ommited Equality, Comparable, GetHashCode, functionality for brevity.
}
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制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?