给定代表某人生日的DateTime,我如何计算他们的年龄(以年为单位)?
当前回答
这是我们在这里使用的版本。它有效,而且相当简单。这与Jeff的想法相同,但我认为它更清晰一点,因为它分离了减法的逻辑,所以更容易理解。
public static int GetAge(this DateTime dateOfBirth, DateTime dateAsAt)
{
return dateAsAt.Year - dateOfBirth.Year - (dateOfBirth.DayOfYear < dateAsAt.DayOfYear ? 0 : 1);
}
如果你认为这类事情不清楚,你可以扩展三元运算符使其更清晰。
显然,这是作为DateTime上的一个扩展方法完成的,但很明显,您可以抓取一行代码来完成工作并将其放在任何位置。这里我们有另一个传入DateTime的Extension方法重载。
其他回答
var startDate = new DateTime(2015, 04, 05);//your start date
var endDate = DateTime.Now;
var years = 0;
while(startDate < endDate)
{
startDate = startDate.AddYears(1);
if(startDate < endDate)
{
years++;
}
}
这里有一个小的C#代码示例,我总结了一下,请注意边缘情况,特别是闰年,并不是所有上述解决方案都考虑到这些情况。将答案推出来作为DateTime可能会导致问题,因为你可能会在一个特定的月份中投入太多的时间,例如2月的30天。
public string LoopAge(DateTime myDOB, DateTime FutureDate)
{
int years = 0;
int months = 0;
int days = 0;
DateTime tmpMyDOB = new DateTime(myDOB.Year, myDOB.Month, 1);
DateTime tmpFutureDate = new DateTime(FutureDate.Year, FutureDate.Month, 1);
while (tmpMyDOB.AddYears(years).AddMonths(months) < tmpFutureDate)
{
months++;
if (months > 12)
{
years++;
months = months - 12;
}
}
if (FutureDate.Day >= myDOB.Day)
{
days = days + FutureDate.Day - myDOB.Day;
}
else
{
months--;
if (months < 0)
{
years--;
months = months + 12;
}
days = days + (DateTime.DaysInMonth(FutureDate.AddMonths(-1).Year, FutureDate.AddMonths(-1).Month) + FutureDate.Day) - myDOB.Day;
}
//add an extra day if the dob is a leap day
if (DateTime.IsLeapYear(myDOB.Year) && myDOB.Month == 2 && myDOB.Day == 29)
{
//but only if the future date is less than 1st March
if(FutureDate >= new DateTime(FutureDate.Year, 3,1))
days++;
}
return "Years: " + years + " Months: " + months + " Days: " + days;
}
我想添加希伯来文日历计算(或其他系统。全球化日历可以以相同的方式使用),使用此线程中的重写函数:
Public Shared Function CalculateAge(BirthDate As DateTime) As Integer
Dim HebCal As New System.Globalization.HebrewCalendar ()
Dim now = DateTime.Now()
Dim iAge = HebCal.GetYear(now) - HebCal.GetYear(BirthDate)
Dim iNowMonth = HebCal.GetMonth(now), iBirthMonth = HebCal.GetMonth(BirthDate)
If iNowMonth < iBirthMonth Or (iNowMonth = iBirthMonth AndAlso HebCal.GetDayOfMonth(now) < HebCal.GetDayOfMonth(BirthDate)) Then iAge -= 1
Return iAge
End Function
我创建了一个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.
}
以下方法(从.NET类DateDiff的时间段库中提取)考虑区域性信息的日历:
// ----------------------------------------------------------------------
private static int YearDiff( DateTime date1, DateTime date2 )
{
return YearDiff( date1, date2, DateTimeFormatInfo.CurrentInfo.Calendar );
} // YearDiff
// ----------------------------------------------------------------------
private static int YearDiff( DateTime date1, DateTime date2, Calendar calendar )
{
if ( date1.Equals( date2 ) )
{
return 0;
}
int year1 = calendar.GetYear( date1 );
int month1 = calendar.GetMonth( date1 );
int year2 = calendar.GetYear( date2 );
int month2 = calendar.GetMonth( date2 );
// find the the day to compare
int compareDay = date2.Day;
int compareDaysPerMonth = calendar.GetDaysInMonth( year1, month1 );
if ( compareDay > compareDaysPerMonth )
{
compareDay = compareDaysPerMonth;
}
// build the compare date
DateTime compareDate = new DateTime( year1, month2, compareDay,
date2.Hour, date2.Minute, date2.Second, date2.Millisecond );
if ( date2 > date1 )
{
if ( compareDate < date1 )
{
compareDate = compareDate.AddYears( 1 );
}
}
else
{
if ( compareDate > date1 )
{
compareDate = compareDate.AddYears( -1 );
}
}
return year2 - calendar.GetYear( compareDate );
} // YearDiff
用法:
// ----------------------------------------------------------------------
public void CalculateAgeSamples()
{
PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2009, 02, 28 ) );
// > Birthdate=29.02.2000, Age at 28.02.2009 is 8 years
PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2012, 02, 28 ) );
// > Birthdate=29.02.2000, Age at 28.02.2012 is 11 years
} // CalculateAgeSamples
// ----------------------------------------------------------------------
public void PrintAge( DateTime birthDate, DateTime moment )
{
Console.WriteLine( "Birthdate={0:d}, Age at {1:d} is {2} years", birthDate, moment, YearDiff( birthDate, moment ) );
} // PrintAge
推荐文章
- HTTP POST返回错误:417“期望失败。”
- 如何在。net中创建和使用资源
- 为什么Path。以Path.DirectorySeparatorChar开头的文件名合并不正确?
- 如何在c#中获得正确的时间戳
- Linq选择列表中存在的对象(A,B,C)
- c# .NET中的App.config是什么?如何使用它?
- c#:如何获得一个字符串的第一个字符?
- String类中的什么方法只返回前N个字符?
- 如何在PowerShell格式化日期时间
- 我如何提高ASP。NET MVC应用程序性能?
- 更好的方法将对象转换为int类型
- 我可以将c#字符串值转换为转义字符串文字吗?
- 在c#中转换char到int
- c#中朋友的对等物是什么?
- 关键字使用virtual+override vs. new