给定代表某人生日的DateTime,我如何计算他们的年龄(以年为单位)?


当前回答

private int GetAge(int _year, int _month, int _day
{
    DateTime yourBirthDate= new DateTime(_year, _month, _day);

    DateTime todaysDateTime = DateTime.Today;
    int noOfYears = todaysDateTime.Year - yourBirthDate.Year;

    if (DateTime.Now.Month < yourBirthDate.Month ||
        (DateTime.Now.Month == yourBirthDate.Month && DateTime.Now.Day < yourBirthDate.Day))
    {
        noOfYears--;
    }

    return  noOfYears;
}

其他回答

这不是一个直接的答案,但更多的是从准科学的角度对当前问题进行哲学推理。

我认为,这个问题并没有具体说明衡量年龄的单位或文化,大多数答案似乎都假设了一个整数年表示。时间的国际单位制单位是秒,因此正确的通用答案应该是(当然,假设标准化日期时间,不考虑相对论效应):

var lifeInSeconds = (DateTime.Now.Ticks - then.Ticks)/TickFactor;

在基督教以年计算年龄的方法中:

var then = ... // Then, in this case the birthday
var now = DateTime.UtcNow;
int age = now.Year - then.Year;
if (now.AddYears(-age) < then) age--;

在金融领域,当计算通常被称为日计数分数(Day Count Fraction)的东西时,也存在类似的问题,该分数大致是给定时期的年数。年龄问题确实是一个衡量时间的问题。

实际/实际(正确计算所有天数)惯例示例:

DateTime start, end = .... // Whatever, assume start is before end

double startYearContribution = 1 - (double) start.DayOfYear / (double) (DateTime.IsLeapYear(start.Year) ? 366 : 365);
double endYearContribution = (double)end.DayOfYear / (double)(DateTime.IsLeapYear(end.Year) ? 366 : 365);
double middleContribution = (double) (end.Year - start.Year - 1);

double DCF = startYearContribution + endYearContribution + middleContribution;

另一种很常见的衡量时间的方法通常是“序列化”(命名这一日期惯例的家伙一定是认真的“trippin”):

DateTime start, end = .... // Whatever, assume start is before end
int days = (end - start).Days;

我想知道,在相对论年龄(以秒为单位)变得比迄今为止地球围绕太阳周期的粗略近似更有用之前,我们还需要多长时间:)或者换句话说,当一个周期必须给定一个位置或一个表示其自身运动的函数才能有效时:)

这是我们在这里使用的版本。它有效,而且相当简单。这与Jeff的想法相同,但我认为它更清晰一点,因为它分离了减法的逻辑,所以更容易理解。

public static int GetAge(this DateTime dateOfBirth, DateTime dateAsAt)
{
    return dateAsAt.Year - dateOfBirth.Year - (dateOfBirth.DayOfYear < dateAsAt.DayOfYear ? 0 : 1);
}

如果你认为这类事情不清楚,你可以扩展三元运算符使其更清晰。

显然,这是作为DateTime上的一个扩展方法完成的,但很明显,您可以抓取一行代码来完成工作并将其放在任何位置。这里我们有另一个传入DateTime的Extension方法重载。

简单易懂的解决方案。

// Save today's date.
var today = DateTime.Today;

// Calculate the age.
var age = today.Year - birthdate.Year;

// Go back to the year in which the person was born in case of a leap year
if (birthdate.Date > today.AddYears(-age)) age--;

然而,这假设你在寻找西方的时代观念,而不是使用东亚的推算法。

public string GetAge(this DateTime birthdate, string ageStrinFormat = null)
{
    var date = DateTime.Now.AddMonths(-birthdate.Month).AddDays(-birthdate.Day);
    return string.Format(ageStrinFormat ?? "{0}/{1}/{2}",
        (date.Year - birthdate.Year), date.Month, date.Day);
}

我创建了一个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.
}