关于.NET:我如何用C#来计算某人的年龄?

关于.NET:我如何用C#来计算某人的年龄?

How do I calculate someone's age in C#?

如果一个DateTime代表一个人的生日,我如何计算他们的年龄(以年计)?


简单易懂的解决方案。

1
2
3
4
5
6
// Save today's date.
var today = DateTime.Today;
// Calculate the age.
var age = today.Year - birthdate.Year;
// Go back to the year the person was born in case of a leap year
if (birthdate > today.AddYears(-age)) age--;

然而,这假设你是在寻找西方的年龄观念,而不是使用东亚计算。


这是一种奇怪的方法,但是如果您将日期格式化为yyyymmdd,并从当前日期中减去出生日期,则删除最后4位您的年龄:)

我不知道C,但我相信这可以用任何语言。

1
20080814 - 19800703 = 280111

删除最后4位=28

C代码:

1
2
3
int now = int.Parse(DateTime.Now.ToString("yyyyMMdd"));
int dob = int.Parse(dateOfBirth.ToString("yyyyMMdd"));
int age = (now - dob) / 10000;

或者不使用扩展方法形式的所有类型转换。省略错误检查:

1
2
3
4
5
6
7
8
9
public static Int32 GetAge(this DateTime dateOfBirth)
{
    var today = DateTime.Today;

    var a = (today.Year * 100 + today.Month) * 100 + today.Day;
    var b = (dateOfBirth.Year * 100 + dateOfBirth.Month) * 100 + dateOfBirth.Day;

    return (a - b) / 10000;
}

我不知道如何接受错误的解决方案。正确的c片段是由Michael Stum编写的。

下面是一个测试片段:

1
2
3
4
5
6
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

这里有一些方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;
}

我认为到目前为止,任何答案都不能为不同的文化计算年龄提供依据。例如,参见东亚年龄推算与西方年龄推算。

任何真正的答案都必须包括本地化。在这个例子中,策略模式可能是有序的。


简单的答案是应用AddYears,如下所示,因为这是唯一一种将年份添加到闰年2月29日并在普通年份中获得2月28日正确结果的本地方法。

有些人认为3月1日是跳跃者的生日,但是.net和任何官方规则都不支持这一点,也没有共同的逻辑解释为什么一些2月份出生的人在另一个月里会有75%的生日。

此外,一个年龄方法可以作为对DateTime的扩展而添加。通过这种方法,您可以以最简单的方式获得年龄:

  • 列表项
  • int age=出生日期.age();

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    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;
        }
    }

    现在,运行此测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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岁

    输出:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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日之后:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {
        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
    }

    我的建议

    1
    int age = (int) ((DateTime.Now - bday).TotalDays/365.242199);

    这一年的变化似乎是在正确的日期。(我抽查了107岁以下的儿童)


    另一个功能,不是我的,而是在网络上找到的,并对其进行了一些改进:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public static int GetAge(DateTime birthDate)
    {
        DateTime n = DateTime.Now; // To avoid a race condition around midnight
        int age = n.Year - birthDate.Year;

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

        return age;
    }

    我只想到两件事:那些不使用公历的国家的人呢?现在是服务器特定的区域性。我对实际使用亚洲日历一无所知,我不知道是否有一种简单的方法可以在日历之间转换日期,但只是为了防止你对4660年的中国人产生疑问:—)


    要解决的两个主要问题是:

    1。计算准确的年龄-以年、月、日等为单位。

    2。计算人们普遍认为的年龄——人们通常不关心他们到底有多大,他们只关心他们今年的生日是什么时候。

    1的解决方案很明显:

    1
    2
    3
    4
    5
    6
    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的解决办法是在确定总年龄时不那么精确,但被人们认为是精确的。当人们"手动"计算他们的年龄时,通常也会使用它:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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,因为它们会改变闰年中的天数。
    • 为了可读性,我多放了几行

    再给我一张便条…我将为它创建两个静态重载方法,一个用于通用,另一个用于友好使用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static int GetAge(DateTime bithDay, DateTime today)
    {
      //chosen solution method body
    }

    public static int GetAge(DateTime birthDay)
    {
      return GetAge(birthDay, DateTime.Now);
    }

    我参加晚会迟到了,但有一句话:

    1
    int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1;

    这是我们在这里使用的版本。它工作,而且相当简单。这和杰夫的想法是一样的,但我觉得这更清楚一点,因为它区分了减法的逻辑,所以更容易理解。

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

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

    显然,这是在DateTime上作为扩展方法完成的,但是很明显,您可以获取一行代码来完成这项工作,并将其放在任何地方。这里我们有另外一个扩展方法的重载,它在DateTime.Now中传递,只是为了完整性。


    因为闰年,我所知道的最好的方法是:

    1
    2
    DateTime birthDate = new DateTime(2000,3,1);
    int age = (int)Math.Floor((DateTime.Now - birthDate).TotalDays / 365.25D);

    希望这有帮助。


    我用这个:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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;
        }
    }

    这就给了这个问题更多的细节。也许这就是你要找的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    DateTime birth = new DateTime(1974, 8, 29);
    DateTime today = DateTime.Now;
    TimeSpan span = today - birth;
    DateTime age = DateTime.MinValue + span;

    // Make adjustment due to MinValue equalling 1/1/1
    int years = age.Year - 1;
    int months = age.Month - 1;
    int days = age.Day - 1;

    // Print out not only how many years old they are but give months and days as well
    Console.Write("{0} years, {1} months, {2} days", years, months, days);

    我已经创建了一个SQL Server用户定义函数,根据某人的出生日期来计算其年龄。当您需要它作为查询的一部分时,这很有用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    using System;
    using System.Data;
    using System.Data.Sql;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;
    using Microsoft.SqlServer.Server;

    public partial class UserDefinedFunctions
    {
        [SqlFunction(DataAccess = DataAccessKind.Read)]
        public static SqlInt32 CalculateAge(string strBirthDate)
        {
            DateTime dtBirthDate = new DateTime();
            dtBirthDate = Convert.ToDateTime(strBirthDate);
            DateTime dtToday = DateTime.Now;

            // get the difference in years
            int years = dtToday.Year - dtBirthDate.Year;

            // subtract another year if we're before the
            // birth day in the current year
            if (dtToday.Month < dtBirthDate.Month || (dtToday.Month == dtBirthDate.Month && dtToday.Day < dtBirthDate.Day))
                years=years-1;

            int intCustomerAge = years;
            return intCustomerAge;
        }
    };


    我花了一些时间来研究这个问题,并想出了这个方法来计算一个人的年龄,以年、月和日为单位。我已经针对2月29日的问题和闰年进行了测试,它似乎有效,我很感谢任何反馈:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    public void 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 +=
                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++;
        }

    }

    还有一个答案:

    1
    2
    3
    4
    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天的天数。

    其工作原因(从这里起)的解释是:

    Let's set Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day

    age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 372

    We know that what we need is either Yn-Yb if the date has already been reached, Yn-Yb-1 if it has not.

    a) If Mn, we have -341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30

    -371 <= 31*(Mn - Mb) + (Dn - Db) <= -1

    With integer division

    (31*(Mn - Mb) + (Dn - Db)) / 372 = -1

    b) If Mn=Mb and Dn, we have 31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1

    With integer division, again

    (31*(Mn - Mb) + (Dn - Db)) / 372 = -1

    c) If Mn>Mb, we have 31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30

    1 <= 31*(Mn - Mb) + (Dn - Db) <= 371

    With integer division

    (31*(Mn - Mb) + (Dn - Db)) / 372 = 0

    d) If Mn=Mb and Dn>Db, we have 31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 30

    With integer division, again

    (31*(Mn - Mb) + (Dn - Db)) / 372 = 0

    e) If Mn=Mb and Dn=Db, we have 31*(Mn - Mb) + Dn-Db = 0

    and therefore (31*(Mn - Mb) + (Dn - Db)) / 372 = 0


    我们需要考虑1岁以下的人吗?作为中国文化,我们将幼儿的年龄描述为2个月或4周。

    下面是我的实现,它不像我想象的那么简单,特别是处理2/28这样的日期。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    public static string HowOld(DateTime birthday, DateTime now)
    {
        if (now < birthday)
            throw new ArgumentOutOfRangeException("birthday must be less than now.");

        TimeSpan diff = now - birthday;
        int diffDays = (int)diff.TotalDays;

        if (diffDays > 7)//year, month and week
        {
            int age = now.Year - birthday.Year;

            if (birthday > now.AddYears(-age))
                age--;

            if (age > 0)
            {
                return age + (age > 1 ?" years" :" year");
            }
            else
            {// month and week
                DateTime d = birthday;
                int diffMonth = 1;

                while (d.AddMonths(diffMonth) <= now)
                {
                    diffMonth++;
                }

                age = diffMonth-1;

                if (age == 1 && d.Day > now.Day)
                    age--;

                if (age > 0)
                {
                    return age + (age > 1 ?" months" :" month");
                }
                else
                {
                    age = diffDays / 7;
                    return age + (age > 1 ?" weeks" :" week");
                }
            }
        }
        else if (diffDays > 0)
        {
            int age = diffDays;
            return age + (age > 1 ?" days" :" day");
        }
        else
        {
            int age = diffDays;
            return"just born";
        }
    }

    此实现已通过以下测试用例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    [TestMethod]
    public void TestAge()
    {
        string age = HowOld(new DateTime(2011, 1, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 year", age);

        age = HowOld(new DateTime(2011, 11, 30), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 year", age);

        age = HowOld(new DateTime(2001, 1, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("11 years", age);

        age = HowOld(new DateTime(2012, 1, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("10 months", age);

        age = HowOld(new DateTime(2011, 12, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("11 months", age);

        age = HowOld(new DateTime(2012, 10, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 month", age);

        age = HowOld(new DateTime(2008, 2, 28), new DateTime(2009, 2, 28));
        Assert.AreEqual("1 year", age);

        age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 2, 28));
        Assert.AreEqual("11 months", age);

        age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 3, 28));
        Assert.AreEqual("1 year", age);

        age = HowOld(new DateTime(2009, 1, 28), new DateTime(2009, 2, 28));
        Assert.AreEqual("1 month", age);

        age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1));
        Assert.AreEqual("1 month", age);

        // NOTE.
        // new DateTime(2008, 1, 31).AddMonths(1) == new DateTime(2009, 2, 28);
        // new DateTime(2008, 1, 28).AddMonths(1) == new DateTime(2009, 2, 28);
        age = HowOld(new DateTime(2009, 1, 31), new DateTime(2009, 2, 28));
        Assert.AreEqual("4 weeks", age);

        age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 2, 28));
        Assert.AreEqual("3 weeks", age);

        age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1));
        Assert.AreEqual("1 month", age);

        age = HowOld(new DateTime(2012, 11, 5), new DateTime(2012, 11, 30));
        Assert.AreEqual("3 weeks", age);

        age = HowOld(new DateTime(2012, 11, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("4 weeks", age);

        age = HowOld(new DateTime(2012, 11, 20), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 week", age);

        age = HowOld(new DateTime(2012, 11, 25), new DateTime(2012, 11, 30));
        Assert.AreEqual("5 days", age);

        age = HowOld(new DateTime(2012, 11, 29), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 day", age);

        age = HowOld(new DateTime(2012, 11, 30), new DateTime(2012, 11, 30));
        Assert.AreEqual("just born", age);

        age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 2, 28));
        Assert.AreEqual("8 years", age);

        age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 3, 1));
        Assert.AreEqual("9 years", age);

        Exception e = null;

        try
        {
            age = HowOld(new DateTime(2012, 12, 1), new DateTime(2012, 11, 30));
        }
        catch (ArgumentOutOfRangeException ex)
        {
            e = ex;
        }

        Assert.IsTrue(e != null);
    }

    希望能有所帮助。


    保持简单(可能是愚蠢的)。

    1
    2
    3
    DateTime birth = new DateTime(1975, 09, 27, 01, 00, 00, 00);
    TimeSpan ts = DateTime.Now - birth;
    Console.WriteLine("You are approximately" + ts.TotalSeconds.ToString() +" seconds old.");

    我找到的最简单的方法就是这个。它适用于美国和西欧地区。不能和其他地方说话,特别是像中国这样的地方。最多4个额外的比较,在初始计算年龄之后。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public int AgeInYears(DateTime birthDate, DateTime referenceDate)
    {
      Debug.Assert(referenceDate >= birthDate,
                  "birth date must be on or prior to the reference date");

      DateTime birth = birthDate.Date;
      DateTime reference = referenceDate.Date;
      int years = (reference.Year - birth.Year);

      //
      // an offset of -1 is applied if the birth date has
      // not yet occurred in the current year.
      //
      if (reference.Month > birth.Month);
      else if (reference.Month < birth.Month)
        --years;
      else // in birth month
      {
        if (reference.Day < birth.Day)
          --years;
      }

      return years ;
    }

    我仔细研究了这个问题的答案,发现没有人提到闰日出生的监管/法律问题。例如,根据维基百科,如果你在2月29日出生在不同的司法管辖区,你的非闰年生日会有所不同:

    • 在英国和香港:这是一年中的第二天,所以第二天,3月1日是你的生日。
    • 在新西兰:这是前一天,2月28日为驾驶执照,3月1日为其他目的。
    • 台湾:现在是2月28日。

    据我所知,在美国,法规对这一问题保持沉默,这取决于普通法以及各监管机构如何在其法规中定义事物。

    为此,需要改进:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public enum LeapDayRule
    {
      OrdinalDay     = 1 ,
      LastDayOfMonth = 2 ,
    }

    static int ComputeAgeInYears(DateTime birth, DateTime reference, LeapYearBirthdayRule ruleInEffect)
    {
      bool isLeapYearBirthday = CultureInfo.CurrentCulture.Calendar.IsLeapDay(birth.Year, birth.Month, birth.Day);
      DateTime cutoff;

      if (isLeapYearBirthday && !DateTime.IsLeapYear(reference.Year))
      {
        switch (ruleInEffect)
        {
          case LeapDayRule.OrdinalDay:
            cutoff = new DateTime(reference.Year, 1, 1)
                                 .AddDays(birth.DayOfYear - 1);
            break;

          case LeapDayRule.LastDayOfMonth:
            cutoff = new DateTime(reference.Year, birth.Month, 1)
                                 .AddMonths(1)
                                 .AddDays(-1);
            break;

          default:
            throw new InvalidOperationException();
        }
      }
      else
      {
        cutoff = new DateTime(reference.Year, birth.Month, birth.Day);
      }

      int age = (reference.Year - birth.Year) + (reference >= cutoff ? 0 : -1);
      return age < 0 ? 0 : age;
    }

    应注意,此代码假定:

    • 西方(欧洲)的年龄计算,以及
    • 一种日历,如公历,在月底插入一个闰日。

    1
    2
    TimeSpan diff = DateTime.Now - birthdayDateTime;
    string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff);

    我不知道你到底希望它返回给你多少,所以我只做了一个可读的字符串。


    这不是一个直接的答案,而是从准科学的角度对手头的问题进行哲学推理。

    我认为,这个问题并没有具体说明测量年龄的单位和文化,大多数答案似乎都假定一个整型的年度代表。时间的国际单位是second,因此正确的通用答案应该是(当然假定标准化DateTime并且不考虑相对论效应):

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

    以基督教的方式计算年龄,以年为单位:

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

    在金融学中,当计算一些通常被称为日数分数的东西时,也有一个类似的问题,这个分数大概是给定时期的几年。年龄问题实际上是一个衡量时间的问题。

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

    1
    2
    3
    4
    5
    6
    7
    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):

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

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


    这是一个解决方案。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    DateTime dateOfBirth = new DateTime(2000, 4, 18);
    DateTime currentDate = DateTime.Now;

    int ageInYears = 0;
    int ageInMonths = 0;
    int ageInDays = 0;

    ageInDays = currentDate.Day - dateOfBirth.Day;
    ageInMonths = currentDate.Month - dateOfBirth.Month;
    ageInYears = currentDate.Year - dateOfBirth.Year;

    if (ageInDays < 0)
    {
        ageInDays += DateTime.DaysInMonth(currentDate.Year, currentDate.Month);
        ageInMonths = ageInMonths--;

        if (ageInMonths < 0)
        {
            ageInMonths += 12;
            ageInYears--;
        }
    }

    if (ageInMonths < 0)
    {
        ageInMonths += 12;
        ageInYears--;
    }

    Console.WriteLine("{0}, {1}, {2}", ageInYears, ageInMonths, ageInDays);

    这是一个最准确的答案,能够解决2月29日的生日比任何一年2月28日。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public int GetAge(DateTime birthDate)
    {
        int age = DateTime.Now.Year - birthDate.Year;

        if (birthDate.DayOfYear > DateTime.Now.DayOfYear)
            age--;

        return age;
    }

    我有一个定制的方法来计算年龄,加上一个额外的验证消息,以防万一:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    public void GetAge(DateTime dob, DateTime now, out int years, out int months, out int days)
    {
        years = 0;
        months = 0;
        days = 0;

        DateTime tmpdob = new DateTime(dob.Year, dob.Month, 1);
        DateTime tmpnow = new DateTime(now.Year, now.Month, 1);

        while (tmpdob.AddYears(years).AddMonths(months) < tmpnow)
        {
            months++;
            if (months > 12)
            {
                years++;
                months = months - 12;
            }
        }

        if (now.Day >= dob.Day)
            days = days + now.Day - dob.Day;
        else
        {
            months--;
            if (months < 0)
            {
                years--;
                months = months + 12;
            }
            days += DateTime.DaysInMonth(now.AddMonths(-1).Year, now.AddMonths(-1).Month) + now.Day - dob.Day;
        }

        if (DateTime.IsLeapYear(dob.Year) && dob.Month == 2 && dob.Day == 29 && now >= new DateTime(now.Year, 3, 1))
            days++;

    }  

    private string ValidateDate(DateTime dob) //This method will validate the date
    {
        int Years = 0; int Months = 0; int Days = 0;

        GetAge(dob, DateTime.Now, out Years, out Months, out Days);

        if (Years < 18)
            message =  Years +" is too young. Please try again on your 18th birthday.";
        else if (Years >= 65)
            message = Years +" is too old. Date of Birth must not be 65 or older.";
        else
            return null; //Denotes validation passed
    }

    方法在此处调用并传递日期时间值(如果服务器设置为usa locale,则为mm/dd/yyyy)。将此替换为要显示的任何消息框或任何容器:

    1
    2
    3
    4
    5
    6
    DateTime dob = DateTime.Parse("03/10/1982");  

    string message = ValidateDate(dob);

    lbldatemessage.Visible = !StringIsNullOrWhitespace(message);
    lbldatemessage.Text = message ??""; //Ternary if message is null then default to empty string

    请记住,您可以根据自己的喜好设置信息的格式。


    这个解决方案怎么样?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    static string CalcAge(DateTime birthDay)
    {
        DateTime currentDate = DateTime.Now;        
        int approximateAge = currentDate.Year - birthDay.Year;
        int daysToNextBirthDay = (birthDay.Month * 30 + birthDay.Day) -
            (currentDate.Month * 30 + currentDate.Day) ;

        if (approximateAge == 0 || approximateAge == 1)
        {                
            int month =  Math.Abs(daysToNextBirthDay / 30);
            int days = Math.Abs(daysToNextBirthDay % 30);

            if (month == 0)
                return"Your age is:" + daysToNextBirthDay +" days";

            return"Your age is:" + month +" months and" + days +" days"; ;
        }

        if (daysToNextBirthDay > 0)
            return"Your age is:" + --approximateAge +" Years";

        return"Your age is:" + approximateAge +" Years"; ;
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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;
    }

    以下方法(从.NET类的时间段库中提取)考虑区域性信息的日历:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    // ----------------------------------------------------------------------
    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

    用途:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // ----------------------------------------------------------------------
    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

    SQL版本:

    1
    2
    3
    4
    5
    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

    我用斯卡彻2的解来精确计算一个人的年龄,但我需要更进一步,计算他们的月和日以及年。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
        public static Dictionary<string,int> CurrentAgeInYearsMonthsDays(DateTime? ndtBirthDate, DateTime? ndtReferralDate)
        {
            //----------------------------------------------------------------------
            // Can't determine age if we don't have a dates.
            //----------------------------------------------------------------------
            if (ndtBirthDate == null) return null;
            if (ndtReferralDate == null) return null;

            DateTime dtBirthDate = Convert.ToDateTime(ndtBirthDate);
            DateTime dtReferralDate = Convert.ToDateTime(ndtReferralDate);

            //----------------------------------------------------------------------
            // Create our Variables
            //----------------------------------------------------------------------
            Dictionary<string, int> dYMD = new Dictionary<string,int>();
            int iNowDate, iBirthDate, iYears, iMonths, iDays;
            string sDif ="";

            //----------------------------------------------------------------------
            // Store off current date/time and DOB into local variables
            //----------------------------------------------------------------------
            iNowDate = int.Parse(dtReferralDate.ToString("yyyyMMdd"));
            iBirthDate = int.Parse(dtBirthDate.ToString("yyyyMMdd"));

            //----------------------------------------------------------------------
            // Calculate Years
            //----------------------------------------------------------------------
            sDif = (iNowDate - iBirthDate).ToString();
            iYears = int.Parse(sDif.Substring(0, sDif.Length - 4));

            //----------------------------------------------------------------------
            // Store Years in Return Value
            //----------------------------------------------------------------------
            dYMD.Add("Years", iYears);

            //----------------------------------------------------------------------
            // Calculate Months
            //----------------------------------------------------------------------
            if (dtBirthDate.Month > dtReferralDate.Month)
                iMonths = 12 - dtBirthDate.Month + dtReferralDate.Month - 1;
            else
                iMonths = dtBirthDate.Month - dtReferralDate.Month;

            //----------------------------------------------------------------------
            // Store Months in Return Value
            //----------------------------------------------------------------------
            dYMD.Add("Months", iMonths);

            //----------------------------------------------------------------------
            // Calculate Remaining Days
            //----------------------------------------------------------------------
            if (dtBirthDate.Day > dtReferralDate.Day)
                //Logic: Figure out the days in month previous to the current month, or the admitted month.
                //       Subtract the birthday from the total days which will give us how many days the person has lived since their birthdate day the previous month.
                //       then take the referral date and simply add the number of days the person has lived this month.

                //If referral date is january, we need to go back to the following year's December to get the days in that month.
                if (dtReferralDate.Month == 1)
                    iDays = DateTime.DaysInMonth(dtReferralDate.Year - 1, 12) - dtBirthDate.Day + dtReferralDate.Day;      
                else
                    iDays = DateTime.DaysInMonth(dtReferralDate.Year, dtReferralDate.Month - 1) - dtBirthDate.Day + dtReferralDate.Day;      
            else
                iDays = dtReferralDate.Day - dtBirthDate.Day;            

            //----------------------------------------------------------------------
            // Store Days in Return Value
            //----------------------------------------------------------------------
            dYMD.Add("Days", iDays);

            return dYMD;
    }

    我对MarkSoen的答案做了一个小小的修改:我重写了第三行,这样表达式就可以更容易地解析。

    1
    2
    3
    4
    5
    6
    7
    8
    public int AgeInYears(DateTime bday)
    {
        DateTime now = DateTime.Today;
        int age = now.Year - bday.Year;            
        if (bday.AddYears(age) > now)
            age--;
        return age;
    }

    为了清晰起见,我还把它变成了一个函数。


    这个经典的问题值得一个noda时间解决方案。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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;
    }

    用途:

    1
    2
    LocalDate dateOfBirth = new LocalDate(1976, 8, 27);
    int age = GetAge(dateOfBirth);

    您可能还对以下改进感兴趣:

    • 将时钟作为IClock传入,而不是使用SystemClock.Instance,将提高可测试性。

    • 目标时区可能会改变,所以您也需要一个DateTimeZone参数。

    另请参阅我关于这个主题的博客文章:处理生日和其他周年纪念日


    这是用一行来回答这个问题的最简单方法。

    1
    2
    3
    DateTime Dob = DateTime.Parse("1985-04-24");

    int Age = DateTime.MinValue.AddDays(DateTime.Now.Subtract(Dob).TotalHours/24).Year - 1;

    这也适用于闰年。


    哇,我不得不在这里发表我的评论……这么简单的问题有很多答案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private int CalcularIdade(DateTime dtNascimento)
        {
            var nHoje = Convert.ToInt32(DateTime.Today.ToString("yyyyMMdd"));
            var nAniversario = Convert.ToInt32(dtNascimento.ToString("yyyyMMdd"));

            double diff = (nHoje - nAniversario) / 10000;

            var ret = Convert.ToInt32(Math.Truncate(diff));

            return ret;
        }

    希望它能帮助别人,至少能让别人想到……:)


    这很简单,似乎对我的需要是准确的。为了闰年的目的,我做了一个假设,不管这个人选择什么时候庆祝生日,从技术上讲,他们都不会比自己大一岁,直到从上一个生日起365天过去为止(即2月28日不会让他们比自己大一岁)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    DateTime now = DateTime.Today;
    DateTime birthday = new DateTime(1991, 02, 03);//3rd feb

    int age = now.Year - birthday.Year;

    if (now.Month < birthday.Month || (now.Month == birthday.Month && now.Day < birthday.Day))//not had bday this year yet
      age--;

    return age;

    如果您发现任何问题,请通知我们;)


    ==俗语(从月到岁)===

    如果您只是为了共同使用,下面是代码作为您的信息:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    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";
    }

    试验结果如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
        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
        }

    这里有一个datetime扩展程序,它将年龄计算添加到datetime对象中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static class AgeExtender
    {
        public static int GetAge(this DateTime dt)
        {
            int d = int.Parse(dt.ToString("yyyyMMdd"));
            int t = int.Parse(DateTime.Today.ToString("yyyyMMdd"));
            return (t-d)/10000;
        }
    }

    为什么不能这么简单?

    1
    int age = DateTime.Now.AddTicks(0 - dob.Ticks).Year - 1;

    1
    2
    3
    4
    5
    6
    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);
    }

    我认为时间跨度有我们所需要的一切,而不必求助于365.25(或任何其他近似值)。以Aug为例展开:

    1
    2
    3
    4
    DateTime myBD = new DateTime(1980, 10, 10);
    TimeSpan difference = DateTime.Now.Subtract(myBD);

    textBox1.Text = difference.Years +" years" + difference.Months +" Months" + difference.Days +" days";

    只需使用:

    1
    (DateTime.Now - myDate).TotalHours / 8766.0

    当前日期-mydate=TimeSpan,获取总小时数并除以每年总小时数,然后精确获取年龄/月/天…


    我经常依靠手指。我需要找一个日历,以便在事情发生变化时进行计算。这就是我在代码中要做的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    int AgeNow(DateTime birthday)
    {
        return AgeAt(DateTime.Now, birthday);
    }

    int AgeAt(DateTime now, DateTime birthday)
    {
        return AgeAt(now, birthday, CultureInfo.CurrentCulture.Calendar);
    }

    int AgeAt(DateTime now, DateTime birthday, Calendar calendar)
    {
        // My age has increased on the morning of my
        // birthday even though I was born in the evening.
        now = now.Date;
        birthday = birthday.Date;

        var age = 0;
        if (now <= birthday) return age; // I am zero now if I am to be born tomorrow.

        while (calendar.AddYears(birthday, age + 1) <= now)
        {
            age++;
        }
        return age;
    }

    在LinqPad中运行此路径可以得到:

    1
    2
    3
    PASSED: someone born on 28 February 1964 is age 4 on 28 February 1968
    PASSED: someone born on 29 February 1964 is age 3 on 28 February 1968
    PASSED: someone born on 31 December 2016 is age 0 on 01 January 2017

    LinqPad中的代码在这里


    这行吗?

    1
    2
    3
    4
    5
    6
    7
    8
    public override bool IsValid(DateTime value)
    {
        _dateOfBirth =  value;
        var yearsOld = (double) (DateTime.Now.Subtract(_dateOfBirth).TotalDays/365);
        if (yearsOld > 18)
            return true;
        return false;
    }

    我想添加希伯来日历计算(或其他系统。全球化日历可以以相同的方式使用),使用来自此线程的重写函数:

    1
    2
    3
    4
    5
    6
    7
    8
    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


    这里有一个C i的代码示例,请注意边缘案例,特别是闰年,不是所有上述解决方案都考虑到它们。把答案作为一个日期时间推出来可能会导致一些问题,因为你最终可能会在一个特定的月份中花费太多的时间,例如2月的30天。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    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;
    }

    我用过这个问题,我知道,它不太优雅,但它起作用了

    1
    2
    3
    4
    5
    6
    DateTime zeroTime = new DateTime(1, 1, 1);
    var date1 = new DateTime(1983, 03, 04);
    var date2 = DateTime.Now;
    var dif = date2 - date1;
    int years = (zeroTime + dif).Year - 1;
    Log.DebugFormat("Years -->{0}", years);

    1
    2
    var birthDate = ... // DOB
    var resultDate = DateTime.Now - birthDate;

    使用resultDate可以应用TimeSpan属性,无论您想显示它什么。


    这是一个很好的功能…没有计算,很简单。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
        public static string ToAge(this DateTime dob, DateTime? toDate = null)
        {
            if (!toDate.HasValue)
                toDate = DateTime.Now;
            var now = toDate.Value;

            if (now.CompareTo(dob) < 0)
                return"Future date";

            int years = now.Year - dob.Year;
            int months = now.Month - dob.Month;
            int days = now.Day - dob.Day;

            if (days < 0)
            {
                months--;
                days = DateTime.DaysInMonth(dob.Year, dob.Month) - dob.Day + now.Day;
            }

            if (months < 0)
            {
                years--;
                months = 12 + months;
            }


            return string.Format("{0} year(s), {1} month(s), {2} days(s)",
                years,
                months,
                days);
        }

    这里是一个单元测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        [Test]
        public void ToAgeTests()
        {
            var date = new DateTime(2000, 1, 1);
            Assert.AreEqual("0 year(s), 0 month(s), 1 days(s)", new DateTime(1999, 12, 31).ToAge(date));
            Assert.AreEqual("0 year(s), 0 month(s), 0 days(s)", new DateTime(2000, 1, 1).ToAge(date));
            Assert.AreEqual("1 year(s), 0 month(s), 0 days(s)", new DateTime(1999, 1, 1).ToAge(date));
            Assert.AreEqual("0 year(s), 11 month(s), 0 days(s)", new DateTime(1999, 2, 1).ToAge(date));
            Assert.AreEqual("0 year(s), 10 month(s), 25 days(s)", new DateTime(1999, 2, 4).ToAge(date));
            Assert.AreEqual("0 year(s), 10 month(s), 1 days(s)", new DateTime(1999, 2, 28).ToAge(date));

            date = new DateTime(2000, 2, 15);
            Assert.AreEqual("0 year(s), 0 month(s), 28 days(s)", new DateTime(2000, 1, 18).ToAge(date));
        }

    我创建了一个年龄结构,它看起来如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    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.
    }

    下面是一个非常简单且易于理解的示例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    private int CalculateAge()
    {
    //get birthdate
       DateTime dtBirth = Convert.ToDateTime(BirthDatePicker.Value);
       int byear = dtBirth.Year;
       int bmonth = dtBirth.Month;
       int bday = dtBirth.Day;
       DateTime dtToday = DateTime.Now;
       int tYear = dtToday.Year;
       int tmonth = dtToday.Month;
       int tday = dtToday.Day;
       int age = tYear - byear;
       if (bmonth < tmonth)
           age--;
       else if (bmonth == tmonth && bday>tday)
       {
           age--;
       }
    return age;
    }

    只是因为我不认为最清楚的答案是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static int GetAgeByLoop(DateTime birthday)
    {
        var age = -1;

        for (var date = birthday; date < DateTime.Today; date = date.AddYears(1))
            age++;

        return age;
    }

    我只会这么做:

    1
    2
    DateTime birthDay = new DateTime(1990, 05, 23);
    DateTime age = DateTime.Now - birthDay;

    这样你就可以计算出一个人的确切年龄,如果你想的话,可以精确到毫秒。


    How come the MSDN help did not tell you that? It looks so obvious:

    1
    2
    3
    4
    System.DateTime birthTime = AskTheUser(myUser); // :-)
    System.DateTime now = System.DateTime.Now;
    System.TimeSpan age = now - birthTime; //as simple as that
    double ageInDays = age.TotalDays; // will you convert to whatever you want yourself?

    下面是计算某人年龄的最简单方法。计算一个人的年龄是非常简单的,下面是方法!为了使代码正常工作,需要一个名为birthdate的日期时间对象,该对象包含生日。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     C#
            // get the difference in years
            int years = DateTime.Now.Year - BirthDate.Year;
            // subtract another year if we're before the
            // birth day in the current year
            if (DateTime.Now.Month < BirthDate.Month ||
                (DateTime.Now.Month == BirthDate.Month &&
                DateTime.Now.Day < BirthDate.Day))
                years--;
      VB.NET
            ' get the difference in years
            Dim years As Integer = DateTime.Now.Year - BirthDate.Year
            '
    subtract another year if we're before the
            '
    birth day in the current year
            If DateTime.Now.Month < BirthDate.Month Or (DateTime.Now.Month = BirthDate.Month And DateTime.Now.Day < BirthDate.Day) Then
                years = years - 1
            End If


    试试这个解决方案,它起作用了。

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

    通过较少的转换和utcnow,此代码可以处理闰年2月29日出生的人:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public int GetAge(DateTime DateOfBirth)
    {
        var Now = DateTime.UtcNow;
        return Now.Year - DateOfBirth.Year -
            (
                (
                    Now.Month > DateOfBirth.Month ||
                    (Now.Month == DateOfBirth.Month && Now.Day >= DateOfBirth.Day)
                ) ? 0 : 1
            );
    }

    简单代码

    1
    2
     var birthYear=1993;
     var age = DateTime.Now.AddYears(-birthYear).Year;

    计算一个人有多少岁,

    1
    2
    3
    4
    5
    DateTime dateOfBirth;

    int ageInYears = DateTime.Now.Year - dateOfBirth.Year;

    if (dateOfBirth > today.AddYears(-ageInYears )) ageInYears --;

    一个线性答案,

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

    看看这个:

    1
    2
    TimeSpan ts = DateTime.Now.Subtract(Birthdate);
    age = (byte)(ts.TotalDays / 365.25);

    计算最接近年龄的年龄:

    1
    2
    var ts = DateTime.Now - new DateTime(1988, 3, 19);
    var age = Math.Round(ts.Days / 365.0);

    1
    2
    3
    int age = DateTime.Now.Year - birthday.Year;
    if (DateTime.Now.Month < birthday.Month || DateTime.Now.Month == birthday.Month
    && DateTime.Now.Day < birthday.Day) age--;

    我不喜欢这里的许多答案,因为它们需要几行代码来做一个非常简单的日期数学计算(请保存您对其他文化中年龄计算的所有评论,除非您想发布一个涵盖它们的答案)。我的一行程序,使用C、sqlserver、mysql等中存在的简单日期数学和数学函数,是:

    1
    year(@today)-year(@birthDate)+floor((month(@today)-month(@birthdate)+floor((day(@today)-day(@birthdate))/31))/12)

    但我也非常喜欢上面马修的答案。任何一种方法都比这里给出的其他答案更有效。


    推荐阅读