给定代表某人生日的DateTime,我如何计算他们的年龄(以年为单位)?
当前回答
还有一个答案:
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
其他回答
我使用这个:
public static class DateTimeExtensions
{
public static int Age(this DateTime birthDate)
{
return Age(birthDate, DateTime.Now);
}
public static int Age(this DateTime birthDate, DateTime offsetDate)
{
int result=0;
result = offsetDate.Year - birthDate.Year;
if (offsetDate.DayOfYear < birthDate.DayOfYear)
{
result--;
}
return result;
}
}
这个经典问题值得野田时间来解决。
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参数。
另请参阅我关于这个主题的博客文章:处理生日和其他周年纪念日
SQL版本:
declare @dd smalldatetime = '1980-04-01'
declare @age int = YEAR(GETDATE())-YEAR(@dd)
if (@dd> DATEADD(YYYY, -@age, GETDATE())) set @age = @age -1
print @age
int Age = new DateTime((DateTime.Now - BirthDate).Ticks).Year -1;
Console.WriteLine("Age {0}", Age);
这可能会起作用:
public override bool IsValid(DateTime value)
{
_dateOfBirth = value;
var yearsOld = (double) (DateTime.Now.Subtract(_dateOfBirth).TotalDays/365);
if (yearsOld > 18)
return true;
return false;
}
推荐文章
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 转换为值类型'Int32'失败,因为物化值为空
- c#中有任何连接字符串解析器吗?
- 如何将python datetime转换为字符串,具有可读格式的日期?
- 在Linq中转换int到字符串到实体的问题
- 是否可以动态编译和执行c#代码片段?
- 创建自定义MSBuild任务时,如何从c#代码获取当前项目目录?
- MSBuild路径
- c#和Java的主要区别是什么?
- 在c#中创建一个特定时区的DateTime
- .NET中的属性是什么?
- csproj文件中的“Service Include”是干什么用的?
- 如何使用try catch进行异常处理是最佳实践
- 替换字符串中第一次出现的模式
- .NET中字节的字面后缀?