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


当前回答

下面是一个测试片段:

DateTime bDay = new DateTime(2000, 2, 29);
DateTime now = new DateTime(2009, 2, 28);
MessageBox.Show(string.Format("Test {0} {1} {2}",
                CalculateAgeWrong1(bDay, now),      // outputs 9
                CalculateAgeWrong2(bDay, now),      // outputs 9
                CalculateAgeCorrect(bDay, now),     // outputs 8
                CalculateAgeCorrect2(bDay, now)));  // outputs 8

这里有一些方法:

public int CalculateAgeWrong1(DateTime birthDate, DateTime now)
{
    return new DateTime(now.Subtract(birthDate).Ticks).Year - 1;
}

public int CalculateAgeWrong2(DateTime birthDate, DateTime now)
{
    int age = now.Year - birthDate.Year;

    if (now < birthDate.AddYears(age))
        age--;

    return age;
}

public int CalculateAgeCorrect(DateTime birthDate, DateTime now)
{
    int age = now.Year - birthDate.Year;

    if (now.Month < birthDate.Month || (now.Month == birthDate.Month && now.Day < birthDate.Day))
        age--;

    return age;
}

public int CalculateAgeCorrect2(DateTime birthDate, DateTime now)
{
    int age = now.Year - birthDate.Year;

    // For leap years we need this
    if (birthDate > now.AddYears(-age)) 
        age--;
    // Don't use:
    // if (birthDate.AddYears(age) > now) 
    //     age--;

    return age;
}

其他回答

一句话的回答:

DateTime dateOfBirth = Convert.ToDateTime("01/16/1990");
var age = ((DateTime.Now - dateOfBirth).Days) / 365;

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

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

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;

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

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

试试这个解决方案,它奏效了。

int age = (Int32.Parse(DateTime.Today.ToString("yyyyMMdd")) - 
           Int32.Parse(birthday.ToString("yyyyMMdd rawrrr"))) / 10000;

简单易懂的解决方案。

// 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--;

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