如何根据 DateTime 类型的生日计算某人的年龄?

How do I calculate someone's age based on a DateTime type birthday?

提问人: 提问时间:8/1/2008 最后编辑:34 revs, 30 users 30%Shaik Raffi 更新时间:8/31/2023 访问量:814509

问:

给定一个人的生日,我如何以年为单位计算他们的年龄?DateTime

C# .NET 日期时间

评论

190赞 Yaur 5/21/2011
到目前为止,所有答案都忽略了,这取决于这个人出生在哪里以及他们现在在哪里。
54赞 Stefan Steiger 10/3/2011
@Yaur:只需将现在+出生时间转换为GMT / UTC,年龄只是一个相对值,因此时区无关紧要。要确定用户的当前时区,可以使用 GeoLocating。
9赞 DDM 7/11/2015
如果我们考虑@Yaur 的跨时区计算建议,夏令时是否应该以任何方式影响计算?
4赞 Andrew Morton 11/11/2017
请注意,对于不到一岁的人,他们的年龄以天、周或月为单位。单元的转换时间可能特定于域。
6赞 Erdogan Kurtur 10/16/2020
正如我们所看到的,年龄没有明确的定义。我遇到的许多女性倾向于将她们的生存时间四舍五入到一整年,直到二十多岁,然后她们开始四舍五入。我出生于 1 月 3 日,所以我只是从我的出生年份中减去今年,不管是哪一天。有些人认为,如果你出生在闰日,你的年龄比例为1/4。如果你出生在闰秒怎么办?8个月大的宝宝算1吗?如果我飞到西方,我会变得更年轻吗?如果我的心脏停止了一分钟,我应该把它包括在计算中吗?

答:

56赞 5 revs, 3 users 62%Nick Berardi #1

由于闰年和一切,我所知道的最好的方式是:

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

评论

2赞 lidqy 9/5/2021
越野车,只是因为它不能处理闰年/天。如果你在生日那天运行它,它会有一半的时间计算错误的年龄。
94赞 6 revs, 4 users 74%Michael Stum #2

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

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

我想到的只有两件事:来自不使用公历的国家的人呢?我认为 DateTime.Now 属于特定于服务器的区域性。我对实际使用亚洲日历的知识完全为零,我不知道是否有一种简单的方法可以在日历之间转换日期,但以防万一您想知道 4660 年的那些中国人:-)

评论

0赞 webdad3 11/10/2016
这似乎可以最好地处理不同的区域(日期格式)。
2411赞 29 revs, 18 users 16%Mike Polen #3

一个易于理解和简单的解决方案。

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

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

评论

97赞 Lars D 11/10/2009
此答案不适用于所有区域设置和所有年龄段。一些国家跳过了当前在世人口出生后的日期,包括俄罗斯(1918年)、希腊(1924年)和土耳其(1926年)。
40赞 Øyvind 11/16/2010
实际上,这仍然不完全正确。此代码假定“bday”是 DateTime 的日期部分。这是一个边缘情况(我猜大多数人只会传递日期而不是日期时间),但如果你将生日作为日期和时间传递,并且时间大于 00:00:00,那么你会遇到 Danvil 指出的错误。设置 bday = bday。Date 解决了这个问题。
8赞 AbbathCL 3/17/2021
这是 12 年,但你为什么不减去 brithday - 今天晚些时候去时间跨度,你可以在没有 if 的情况下得到它。
4赞 Wouter 7/22/2022
@AbbathCl:时间跨度没有年份。
6赞 M Stoerzel 9/26/2022
我在这里遗漏了什么吗?我想这些日子完全不见了。如果此人在 8 月 1 日过生日,而您在 7 月 31 日运行脚本,则获得的结果与在 8 月 1 日运行脚本时的结果相同,但此人比您大一岁。
5赞 drizin 12/6/2022
我认为评论(提到闰年)具有误导性。我想正确的解释是:(1) 如果你出生于 1980 年,现在是 2022 年,那么你将在今年的某个地方年满 42 岁——所以.(2) 如果你的生日今年还没有到来,请减去一:int age = DateTime.Today.Year - dateOfBirth.Yearif (dateOfBirth.Date.AddYears(age) > DateTime.Today) age--
46赞 3 revs, 3 users 64%David Wengier #4

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

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

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

显然,这是作为扩展方法完成的,但显然您可以获取完成工作的那一行代码并将其放在任何地方。在这里,我们有另一个传入的 Extension 方法的重载,只是为了完整起见。DateTimeDateTime.Now

评论

11赞 Doug McClean 12/23/2008
我认为这可能会偏离一天,而 dateOfBirth 或 dateAsAt 恰好落在闰年。考虑 2003 年 3 月 1 日出生的人在 2004 年 2 月 29 日的年龄。要纠正此问题,您需要对 (Month, DayOfMonth) 对进行字典比较,并将其用于条件。
4赞 dotjoe 1/30/2009
它也不会显示你生日时的正确年龄。
1115赞 13 revs, 9 users 29%ScArcher2 #5

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

我不懂 C#,但我相信这适用于任何语言。

20080814 - 19800703 = 280111 

删除最后 4 位数字 = 。28

C# 代码:

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

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

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

评论

13赞 Patrik 7/3/2015
实际上,这非常适合在带有日期时间字段的 MS-SQL 上使用(自 01-011900 以来的总天数)
9赞 GalacticCowboy 9/4/2015
@numerek 请发布您建议的修改作为他们自己的答案。就其价值而言,当前年份乘以 10000 远未达到整数溢出,相差两个数量级。20,150,000 与 2,147,483,648
2赞 Jamie Kitson 2/13/2018
这个答案假设闰日婴儿的生日是在非闰年的 3 月 1 日。
12赞 Rufus L 6/15/2018
@LongChalk .去掉最后 4 位数字,您就有了(隐含的)年龄。你是怎么得到的?20180101 - 20171231 = 887001
2赞 flindeberg 7/4/2018
@RufusL 它 , 不是 ..你正在“数”一万,而你有一万。01floor(8870 / 10000) == 08870
30赞 3 revs, 3 users 95%user2601 #6

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

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;
    }
};
3赞 4 revs, 4 users 64%BigJim #7

我认为 TimeSpan 拥有我们需要的一切,而不必求助于 365.25(或任何其他近似值)。扩展 Aug 的例子:

DateTime myBD = new DateTime(1980, 10, 10);
TimeSpan difference = DateTime.Now.Subtract(myBD);

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

评论

10赞 James Curran 10/4/2008
不。时间跨度为天,但不显示月或年
98赞 4 revs, 4 users 50%James Curran #8

我的建议

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

这似乎让年份在正确的日期发生了变化。(我到107岁。

评论

31赞 MusiGenesis 8/2/2009
我不认为 Harry Patch 会欣赏你的抽查方法:latimes.com/news/obituaries/......
4赞 mpen 8/12/2010
谷歌 说days in a year = 365.242199
13赞 dan04 10/6/2010
公历一年的平均长度是 365.2425 天。
7赞 Peter Perháč 3/9/2011
我想说,这是最简单的解决方案之一,它已经足够好了。谁在乎我是否在X岁生日前半天,程序说我是X岁。该程序或多或少是正确的,尽管不是数学上的。我真的很喜欢这个解决方案。
21赞 ChadT 3/25/2011
^^ 因为有时它很重要。在我的测试中,这在人们的生日那天失败了,它报告说他们比实际年龄年轻。
26赞 3 revs, 3 users 69%Jon #9

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

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++;
    }

}
53赞 4 revs, 3 users 44%SillyMonkey #10

这是一句话:

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

评论

27赞 Kjensen 2/6/2011
这被打破了。可测试:public static int CalculateAge(DateTime dateOfBirth, DateTime dateToCalculateAge) { return new DateTime(dateToCalculateAge.Subtract(dateOfBirth)。蜱)。年 - 1;} ...输入 1990-06-01 并计算他 14 岁生日前一天的年龄 (1990-05-31) 时给出 14 岁。
1赞 lidqy 9/5/2021
@Kjensen 一天的偏移是由实时范围(dateOfBirth 到 dateToCalculateAge)和 DateTime.Subtract 创建的时间范围中 29 月 29 日的不同计数引起的,该时间范围始终与 DateTime.Min(即 1-JAN-0001)隐式比较。从 1990 年 5 月 31 日到 2005 年 6 月 1 日,您有四个这样的闰日,从 0001 年 1 月 1 日到 0015 年 1 月 1 日,您只有三个 2 月 29 日。
17赞 2 revs, 2 users 71%Rajeshwaran S P #11

这是一个解决方案。

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

评论

0赞 JoshYates1980 6/14/2018
使用 string concat,这是可能的: 47 年 11 个月 7 天
423赞 7 revs, 6 users 58%RMA #12

下面是一个测试片段:

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

评论

40赞 Matt Johnson-Pint 8/17/2014
虽然此代码有效,但它断言在闰日出生的人在非闰年的 3 月 1 日而不是 2 月 28 日达到下一年的年龄。实际上,任何一种选择都可能是正确的维基百科对此有话要说。因此,虽然你的代码没有“错误”,但公认的解决方案也不是。
29赞 jfren484 7/13/2016
@MattJohnson我认为这实际上是正确的。如果我的生日是 2 月 29 日,那么 2 月 28 日我的生日还没有过去,我应该和 2 月 27 日的年龄一样。然而,在3月1日,我们已经过了我的生日,我应该是下一个年龄。在美国,销售酒类的企业会有一个标志,上面写着“如果你在YYYY的这一天之后出生,你就不能购买酒类”(YYYY每年都在变化)。这意味着 2 月 29 日出生的人不能在 2 月 28 日年满 21 岁(大多数地方)购买酒精,并支持他们直到 3 月 1 日才大一岁的想法。
7赞 Matt Johnson-Pint 7/13/2016
@jfren484 - 阅读维基百科文章。它因司法管辖区而异。
13赞 Disillusioned 3/4/2017
@jfren484 你的主张与哲学完全无关;但一切都与你自己的个人感受有关。当一个人在2月29日出生时,“年龄”基本上并不重要,除非年龄形成了“法定年龄界限”(例如,可以买酒、投票、领取养老金、参军、获得驾驶执照)。考虑美国的饮酒年龄(21 岁):对于大多数人来说,这是 7670 天。如果在闰年2月29日之前出生或从闰年前的3月1日开始出生,则为7671天。如果出生于2月29日:2月28日是7670天,3月1日是7671天。选择是任意的,它可以采取任何一种方式。
9赞 jfren484 3/5/2017
@CraigYoung 你不明白我在哲学上的意思。我用这个词来对比法律。如果一个人正在编写一份需要知道一个人法定年龄的申请,那么他们需要知道的只是他们的申请在/用于/用于对待 2 月 29 日出生的人的法律管辖区。然而,如果我们谈论的是应该如何对待它,那么根据定义,这就是哲学。是的,我给出的意见是我自己的意见,但正如我所说,我认为为 3 月 1 日争论比为 2 月 28 日争论更容易。
4赞 6 revs, 5 users 64%azamsharp #13

这可能有效:

public override bool IsValid(DateTime value)
{
    _dateOfBirth =  value;
    var yearsOld = (double) (DateTime.Now.Subtract(_dateOfBirth).TotalDays/365);
    if (yearsOld > 18)
        return true;
    return false;
}

评论

6赞 Chris Shouts 5/5/2010
哇。为什么 value 是对象而不是 DateTime?方法签名应该是 2 月 29 日出生的人呢?谁说我们试图检查用户是否至少年满 18 岁?问题是“我如何计算某人的年龄?public override bool Is18OrOlder(DateTime birthday)
1赞 azamsharp 5/5/2010
这是怎么发生的?我什至不记得将 IsValid 作为对象。它应该是 DateTime!
2赞 T_Bacon 3/28/2018
而不是语句,为什么不使用ifreturn yearsOld > 18;
2赞 2 revs, 2 users 71%Frederik Gheysels #14

我创建了一个 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.
}
4赞 Jon #15

这是我敲出的 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;
}

评论

1赞 Jerry 6/9/2012
我最喜欢这个解决方案,但是,在计算月份时,它需要是 if(months >= 12)。尝试 6-8-2012 - 6-4-1993 进行测试。
37赞 4 revs, 4 users 78%Elmer #16

我用这个:

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;
    }
}
21赞 2 revs, 2 users 71%user181261 #17

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

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.");

评论

1赞 Lazlow 9/22/2011
TimeSpan 是我的首选,但发现它不提供 TotalYears 属性。你可以试试(ts.TotalDays / 365) - 但它不考虑闰年等。
13赞 3 revs, 3 users 67%AEMLoviji #18
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;
}
21赞 8 revs, 5 users 66%Nicholas Carey #19

我发现的最简单的方法就是这个。它适用于美国和西欧区域设置。不能与其他地方交谈,尤其是像中国这样的地方。在初始年龄计算之后,最多进行 4 次额外比较。

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日。

据我所知,在美国,法规对此事保持沉默,将其留给普通法以及各种监管机构如何在其法规中定义事物。

为此,改进了:

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

应该注意的是,此代码假定:

  • 西方(欧洲)对年龄的计算,以及
  • 日历,如公历,在月末插入一个闰日。
126赞 6 revs, 6 users 86%camelCasus #20

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

有些人认为 3 月 1 日是跳跃者的生日,但 .Net 和任何官方规则都不支持这一点,通常的逻辑也无法解释为什么一些 2 月出生的人应该在另一个月拥有 75% 的生日。

此外,Age 方法本身可以作为扩展添加到 。通过这种方式,您可以以最简单的方式获得年龄:DateTime

  1. 列表项

int age = 出生日期.Age();

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

现在,运行以下测试:

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

输出:

{
    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-02-28:

{
    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
}

评论

6赞 CyberClaw 7/25/2018
关于在3月1日过29日生日的评论,从技术上讲,在28日过生日还为时过早(实际上提前了1天)。1日晚了一天。但是由于生日介于两者之间,因此使用1号来计算非闰年的年龄对我来说更有意义,因为那个人在每年的3月1日(以及2日和3日)确实是那么大,而不是在2月28日。
3赞 marsze 12/12/2018
从软件设计的角度来看,将其编写为扩展方法对我来说没有多大意义。?date.Age(other)
4赞 A.G. 9/25/2021
@marsze,我认为如果你对变量进行相应的命名,这确实很有意义。dob.Age(toDay)
14赞 4 revs, 4 users 66%Doron #21

这个解决方案怎么样?

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"; ;
}
62赞 5 revs, 2 users 96%Thetam #22

2 要解决的主要问题是:

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

2.计算普遍感知的年龄 - 人们通常不在乎他们到底多大了,他们只关心他们当年的生日是什么时候。


1 的解决方案是显而易见的:

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 的解决方案在确定总年龄方面并不那么精确,但被人们认为是精确的。当人们“手动”计算年龄时,他们通常也会使用它:

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,因为它们会改变闰年的天数
  • 为了便于阅读,我在那里多了几行

再说一点......我会为它创建 2 个静态重载方法,一个用于通用,第二个用于使用友好性:

public static int GetAge(DateTime bithDay, DateTime today) 
{ 
  //chosen solution method body
}

public static int GetAge(DateTime birthDay) 
{ 
  return GetAge(birthDay, DateTime.Now);
}
10赞 2 revs, 2 users 99%user687474 #23

以下方法(摘自 .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
4赞 3 revs, 3 users 67%B2K #24

下面是一个 DateTime 扩展程序,用于将年龄计算添加到 DateTime 对象。

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

评论

4赞 Yaur 5/21/2011
呃,不要这样做。ToString 和 int。解析都相对昂贵,虽然我反对微优化,但在扩展方法中隐藏昂贵的函数,这本应是微不足道的操作,这不是一个好主意。
2赞 David Schmitt 5/30/2011
此外,这是 ScArcher2 答案的副本:stackoverflow.com/questions/9/......
0赞 B2K 9/9/2011
Yaur,我真的很喜欢 Elmer 的解决方案,它依赖于 DayOfYear,可能比我的更有效率。请注意,我的目标不是改变 ScArcher2 的算法,我觉得这很不礼貌。它只是为了展示如何实现扩展方法。
8赞 3 revs, 2 users 74%cdiggins #25

我对 Mark Soen 的回答做了一个小改动:我重写了第三行,以便可以更轻松地解析表达式。

public int AgeInYears(DateTime bday)
{
    DateTime now = DateTime.Today;
    int age = now.Year - bday.Year;            
    if (bday.AddYears(age) > now) 
        age--;
    return age;
}

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

9赞 3 revs, 2 users 99%Dylan Hayes #26

我使用 ScArcher2 的解决方案来准确计算一个人的年龄,但我需要更进一步,计算他们的月份和日期以及年份。

    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;
}
3赞 3 revs, 3 users 65%Moshe L #27

我想添加希伯来历计算(或其他System.Globalization日历可以以相同的方式使用),使用这个线程中重写的函数:

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

评论

0赞 Protiguous 6/5/2020
该问题要求,“在 C# 中,如何计算某人的年龄......”。
0赞 Moshe L 6/7/2020
对于这个想法,C# 和 VB 是相同的。
9赞 3 revs, 3 users 89%musefan #28

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

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;
3赞 4 revs, 4 users 44%Narasimha #29

试试这个解决方案,它正在工作。

int age = (Int32.Parse(DateTime.Today.ToString("yyyyMMdd")) - 
           Int32.Parse(birthday.ToString("yyyyMMdd rawrrr"))) / 10000;
20赞 2 revs, 2 users 97%flindeberg #30

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

我认为,这个问题没有具体说明衡量年龄的单位或文化,大多数答案似乎都假设了整数的年度代表性。时间的 SI 单位是 ,因此正确的通用答案应该是(当然假设归一化并且不考虑相对论效应):secondDateTime

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

在金融领域,在计算通常被称为“日计数分数”的东西时也存在类似的问题,这大致是给定时期的年数。年龄问题实际上是一个时间测量问题。

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

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;

通常,测量时间的另一种非常常见的方法是“序列化”(将这个日期约定命名为“序列化”的家伙一定是认真的绊脚石'):

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

我想知道,我们还要走多久,相对论的年龄(以秒为单位)变得比迄今为止一个人一生中地球绕太阳周期的粗略近似更有用:)或者换句话说,当一个周期必须被赋予一个位置或一个代表运动的函数时,它本身才是有效的:)

评论

0赞 Protiguous 6/5/2020
什么是TickFactor
0赞 flindeberg 6/5/2020
@Protiguous 每秒刻度数,用于将刻度归一化为秒。
21赞 2 revs, 2 users 73%rockXrock #31

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

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

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";
    }
}

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

[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);
}

希望对您有所帮助。

2赞 3 revs, 2 users 76%Stranger #32

这是一个非常简单易懂的例子。

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;
}
32赞 3 revs, 3 users 83%Matthew Watson #33

这是另一个答案:

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 = 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

我们知道,我们需要的是,如果日期已经到来,如果还没有到来。Yn-YbYn-Yb-1

a) 如果 ,我们有Mn<Mb-341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30

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

带整数除法

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

b) 如果 和 ,我们有Mn=MbDn<Db31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1

再次使用整数除法

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

c) 如果 ,我们有Mn>Mb31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30

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

带整数除法

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

d) 如果 和 ,我们有 0Mn=MbDn>Db31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 3

再次使用整数除法

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

e) 如果 和 ,我们有Mn=MbDn=Db31*(Mn - Mb) + Dn-Db = 0

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

2赞 2 revs, 2 users 86%vulcan raven #34

由于转化率和 UtcNow 较少,此代码可以照顾闰年 2 月 29 日出生的人:

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
        );
}

评论

2赞 Peter Mortensen 2/29/2020
就是今天!(下一个是四年后。
1赞 3 revs, 3 users 72%Archit #35

为什么MSDN帮助没有告诉你?它看起来很明显:

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?

评论

11赞 Casey 10/15/2014
嗯,这太棒了,如果你在地球上的零个国家之一,成年人的年龄是以天为单位的。
19赞 2 revs, 2 users 60%Dakotah Hicock #36
TimeSpan diff = DateTime.Now - birthdayDateTime;
string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff);

我不确定你到底希望它如何返回给你,所以我只是做了一个可读的字符串。

38赞 2 revs, 2 users 70%Jacqueline Loriault #37

这为这个问题提供了“更多细节”。也许这就是你要找的

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

评论

1赞 Athanasios Kataras 10/23/2013
这并非一直有效。向 DateTime.MinValue 添加 Span 可以正常工作,但这不考虑闰年等。如果使用 AddYears()、AddMonths 和 AddDays() 函数将 Year、Months 和 Days 添加到 Age,则它不会始终返回 Datetime.Now 日期。
3赞 Jacqueline Loriault 10/24/2013
时间跨度本身会自动考虑 2 个日期之间的闰年,所以我不确定你在做什么。我已经在微软论坛上问过了,微软已经确认它考虑了 2 个日期之间的闰年。
3赞 Athanasios Kataras 10/24/2013
考虑以下两个 senarios。现在是第一个 DateTime.Now 是 2001 年 1 月 1 日,孩子出生于 2000 年 1 月 1 日。2000 年是闰年,结果将是 1 年 0 个月 和 1 天。在第二个 senarion 中,DateTime.Now 是 2002 年 1 月 1 日,孩子出生于 2001 年 1 月 1 日。在这种情况下,结果将是 1 年、0 个月和 0 天。之所以会发生这种情况,是因为您正在添加非闰年的时间跨度。如果 DateTime.MinValue 是闰年,则第一个结果为 1 年,0 年为 11 个月零 30 天。(在代码中尝试)。
1赞 Makotosan 3/18/2015
点赞!我想出了一个几乎相同的解决方案(我使用了 DateTime.MinValue.AddTicks(span.Ticks) 而不是 +,但结果是相同的,您的代码少了几个字符)。
5赞 Athanasios Kataras 3/19/2015
你说得很对,事实并非如此。但如果是这样,那将是结果。为什么这很重要?事实并非如此。无论哪种情况,无论是否跳跃,都有这不起作用的例子。这就是我想展示的。DIFF 是正确的。跨度考虑了闰年。但添加到基准日期则不然。尝试代码中的示例,您会发现我是对的。
-2赞 2 revs, 2 users 75%Dhaval Panchal #38

要计算最接近年龄的年龄:

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

评论

1赞 Kat Lim Ruiz 3/20/2014
不一定是真的。我想正确的做法是除以 365.25 以某种方式解释闰年
13赞 3 revs, 2 users 97%Matt Johnson #39

这个经典的问题值得野田时间解决。

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

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

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

  • 目标时区可能会发生变化,因此您还需要一个参数。DateTimeZone

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

15赞 7 revs, 3 users 49%Knickerless-Noggins #40

我有一个自定义的方法来计算年龄,再加上一个额外的验证消息,以防万一它有帮助:

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
}

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

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

请记住,您可以按照自己喜欢的任何方式设置消息的格式。

-3赞 4 revs, 4 users 53%Pratik Bhoir #41

一句话的答案:

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

评论

0赞 nivs1978 12/15/2020
闰年呢?
16赞 4 revs, 4 users 52%mjb #42

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

public int GetAge(DateTime birthDate)
{
    int age = DateTime.Now.Year - birthDate.Year;

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

    return age;
}




评论

1赞 Peter Mortensen 2/29/2020
就是今天!(下一个是四年后。
1赞 tif 8/18/2020
您可以改用 DateTime.Today,因为时间对计算无关紧要
2赞 2 revs, 2 users 80%dav_i #43

只是因为我认为最重要的答案不是那么清楚:

public static int GetAgeByLoop(DateTime birthday)
{
    var age = -1;

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

    return age;
}
-1赞 3 revs, 2 users 72%mind_overflow #44

看看这个:

TimeSpan ts = DateTime.Now.Subtract(Birthdate);
age = (byte)(ts.TotalDays / 365.25);
3赞 2 revs, 2 users 99%user1210708 #45

这是一个对我有用的功能。没有计算,非常简单。

    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);
    }

下面是一个单元测试:

    [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));
    }

评论

2赞 nathanchere 6/15/2021
“没有计算”?;/
5赞 3 revs, 3 users 44%Lukas #46

它可以是这么简单:

int age = DateTime.Now.AddTicks(0 - dob.Ticks).Year - 1;
2赞 2 revs, 2 users 71%BrunoVT #47

我会简单地这样做:

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

通过这种方式,您可以计算一个人的确切年龄,如果需要,可以精确到毫秒。

评论

2赞 Edward Olamisan 10/3/2015
这是错误的。在您的代码时代中,将是一个 TimeSpan。不是 DateTime。
0赞 Arturo Torres Sánchez 10/6/2015
这样做的问题在于,像“17 年”这样的年龄并不能直接转化为 TimeSpan,因为你不知道这 17 年中哪一个是闰年。
3赞 3 revs, 3 users 70%VhsPiceros #48

对于此问题,我使用了以下内容。我知道它不是很优雅,但它正在工作。

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);
4赞 5 revs, 3 users 94%Ahmed Sabry #49
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);
}
5赞 3 revs, 3 users 67%CathalMF #50

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

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

这也适用于闰年。

评论

3赞 Aman 12/8/2016
你的答案错了一天,它会在前一天给生日
7赞 2 revsJohn_J #51

=== 俗语(从几个月到几年) ===

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

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";
}

测试结果如下:

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; 
10赞 xenedia #52

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  
6赞 2 revs, 2 users 93%André Sobreiro #53

哇,我不得不在这里给出我的答案......对于这样一个简单的问题,有很多答案。

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;
    }
7赞 2 revs, 2 users 63%K1laba #54
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
}
3赞 2 revs, 2 users 78%Sean Kearon #55

我经常指望我的手头。我需要看一个日历来计算事情何时发生变化。这就是我在代码中要做的事情:

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 中运行它会得到这样的结果:

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 中的代码在这里

2赞 2 revs, 2 users 89%Sunny Jangid #56

简单代码

 var birthYear=1993;
 var age = DateTime.Now.AddYears(-birthYear).Year;
0赞 4 revs, 3 users 62%Kaval Patel #57

要计算一个人有多少岁,

DateTime dateOfBirth;

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

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

评论

6赞 sensei 6/11/2019
你刚刚复制了第一个答案,是什么给了帕特尔?
3赞 3 revs, 3 users 67%Moises Conejo #58

只需使用:

(DateTime.Now - myDate).TotalHours / 8766.0

当前日期 - ,得到总小时数并除以每年的总小时数,得到确切的年龄/月份/天数......myDate = TimeSpan

评论

0赞 Wiktor Zychla 6/27/2018
闰年呢?
2赞 wild coder #59

这是计算某人年龄的最简单方法。
计算某人的年龄非常简单,方法如下!为了使代码正常工作,您需要一个名为 BirthDate 的 DateTime 对象,其中包含生日。

 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

评论

5赞 Jon Skeet 2/8/2018
“这是计算某人年龄的最简单方法。这真的不是最简单的方法。使用Noda Time,它只是.int years = Period.Between(birthDate, today).Years;
2赞 Clearer 4/23/2018
@JonSkeet 公平地说,Noda Time 不属于任何 .Net 标准。鉴于此,这是计算一个人年龄(以年为单位)的最简单方法之一。
2赞 4 revs, 4 users 44%user9359822 #60
var birthDate = ... // DOB
var resultDate = DateTime.Now - birthDate;

使用,您可以应用任何要显示的属性。resultDateTimeSpan

0赞 Alexander #61

非常简单的答案

        DateTime dob = new DateTime(1991, 3, 4); 
        DateTime now = DateTime.Now; 
        int dobDay = dob.Day, dobMonth = dob.Month; 
        int add = -1; 
        if (dobMonth < now.Month)
        {
            add = 0;
        }
        else if (dobMonth == now.Month)
        {
            if(dobDay <= now.Day)
            {
                add = 0;
            }
            else
            {
                add = -1;
            }
        }
        else
        {
            add = -1;
        } 
        int age = now.Year - dob.Year + add;

评论

1赞 Suraj Kumar 3/5/2020
应该对 OP 以及未来的读者描述您的答案。
0赞 Võ Quang Hòa 4/15/2020
你的代码并不简单,一团糟。我会写这个,也许你不相信它,但下面的代码做了同样的事情(现在 - dob)。年
0赞 Alexander Díaz #62
int Age = new DateTime((DateTime.Now - BirthDate).Ticks).Year -1;
Console.WriteLine("Age {0}", Age);
-1赞 Abrar Jahin #63

我认为这个问题可以用这样更简单的方法解决——

班级可以是这样的——

using System;

namespace TSA
{
    class BirthDay
    {
        double ageDay;
        public BirthDay(int day, int month, int year)
        {
            DateTime birthDate = new DateTime(year, month, day);
            ageDay = (birthDate - DateTime.Now).TotalDays; //DateTime.UtcNow
        }

        internal int GetAgeYear()
        {
            return (int)Math.Truncate(ageDay / 365);
        }

        internal int GetAgeMonth()
        {
            return (int)Math.Truncate((ageDay % 365) / 30);
        }
    }
}

电话可以是这样的——

BirthDay b = new BirthDay(1,12,1990);
int year = b.GetAgeYear();
int month = b.GetAgeMonth();
0赞 user14273431 #64

我对此一无所知,但我能做的就是:DateTime

using System;
                    
public class Program
{
    public static int getAge(int month, int day, int year) {
        DateTime today = DateTime.Today;
        int currentDay = today.Day;
        int currentYear = today.Year;
        int currentMonth = today.Month;
        int age = 0;
        if (currentMonth < month) {
            age -= 1;
        } else if (currentMonth == month) {
            if (currentDay < day) {
                age -= 1;
            }
        }
        currentYear -= year;
        age += currentYear;
        return age;
    }
    public static void Main()
    {
        int ageInYears = getAge(8, 10, 2007);
        Console.WriteLine(ageInYears);
    }
}

有点令人困惑,但更仔细地查看代码,这一切都是有道理的。

0赞 Wylan Osorio #65
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++;
     }
}
0赞 Rob #66

人们可以这样计算“年龄”(即“西方人”的方式):

public static int AgeInYears(this System.DateTime source, System.DateTime target)
  => target.Year - source.Year is int age && age > 0 && source.AddYears(age) > target ? age - 1 : age < 0 && source.AddYears(age) < target ? age + 1 : age;

如果时间的方向是“负数”,则年龄也将是负数。

可以添加一个分数,它表示从目标到下一个生日累积的年龄量:

public static double AgeInTotalYears(this System.DateTime source, System.DateTime target)
{
  var sign = (source <= target ? 1 : -1);

  var ageInYears = AgeInYears(source, target); // The method above.

  var last = source.AddYears(ageInYears);
  var next = source.AddYears(ageInYears + sign);

  var fractionalAge = (double)(target - last).Ticks / (double)(next - last).Ticks * sign;

  return ageInYears + fractionalAge;
}

分数是经过的时间(从上一个生日开始)与总时间(到下一个生日)的比率。

这两种方法的工作方式相同,无论是在时间上向前还是向后。

3赞 3 revs, 2 users 89%A.G. #67

我强烈建议使用名为 AgeCalculator 的 NuGet 包,因为在计算年龄(闰年、时间成分等)时需要考虑很多事情,而且只有两行代码无法削减它。图书馆给你的不仅仅是一年。它甚至在计算时考虑了时间部分,因此您可以获得包含年、月、日和时间分量的准确年龄。它更先进,可以选择将闰年的 2 月 29 日视为非闰年的 2 月 28 日。

0赞 user17413991 #68

这是一个非常简单的方法:

int Age = DateTime.Today.Year - new DateTime(2000, 1, 1).Year;

评论

0赞 GBU 8/21/2022
很好,只是要注意出生日期仍然在未来的情况。
0赞 3 revsWouter #69

无分支解决方案:

public int GetAge(DateOnly birthDate, DateOnly today)
{
    return today.Year - birthDate.Year + (((today.Month << 5) + today.Day - ((birthDate.Month << 5) + birthDate.Day)) >> 31);
}
1赞 subcoder #70

简单易读,采用互补方法

public static int getAge(DateTime birthDate)
{
    var today = DateTime.Today;
    var age = today.Year - birthDate.Year;
    var monthDiff = today.Month - birthDate.Month;
    var dayDiff = today.Day - birthDate.Day;

    if (dayDiff < 0)
    {
        monthDiff--;
    }
    if (monthDiff < 0)
    {
       age--;
    }
    return age;
}
0赞 Ruchir Gupta #71

不知道为什么没有人尝试这个:

        ushort age = (ushort)DateAndTime.DateDiff(DateInterval.Year, DateTime.Now.Date, birthdate);

它所需要的只是在项目中引用此程序集(如果尚未引用)。using Microsoft.VisualBasic;

1赞 3 revs, 2 users 74%Md Shahriar #72
var EndDate = new DateTime(2022, 4, 21);
var StartDate = new DateTime(1986, 4, 25);
Int32 Months = EndDate.Month - StartDate.Month;
Int32 Years = EndDate.Year - StartDate.Year;
Int32 Days = EndDate.Day - StartDate.Day;

if (Days < 0)
{
    --Months;
}

if (Months < 0)
{
    --Years;
    Months += 12;
}
            
string Ages = Years.ToString() + " Year(s) " + Months.ToString() + " Month(s) ";
0赞 2 revsSam Saarian #73

为什么不能简化以检查出生月份和日期?

第一行 ():假定出生日期尚未出现在年份。然后检查月份和日期,看看是否发生;再增加一年。var year = end.Year - start.Year - 1;end

闰年情景没有特殊待遇。如果不是闰年,则无法将日期(2 月 29 日)创建为日期,因此如果日期是 3 月 1 日,而不是 28 日,则将计算出生日期庆祝活动。下面的函数将把这种情况作为普通日期来覆盖。endend

    static int Get_Age(DateTime start, DateTime end)
    {
        var year = end.Year - start.Year - 1;
        if (end.Month < start.Month)
            return year;
        else if (end.Month == start.Month)
        {
            if (end.Day >= start.Day)
                return ++year;
            return year;
        }
        else
            return ++year;
    }

    static void Test_Get_Age()
    {
        var start = new DateTime(2008, 4, 10); // b-date, leap year BTY
        var end = new DateTime(2023, 2, 1); // end date is before the b-date
        var result1 = Get_Age(start, end);
        var success1 = result1 == 14; // true

        end = new DateTime(2023, 4, 10); // end date is on the b-date
        var result2 = Get_Age(start, end);
        var success2 = result2 == 15; // true

        end = new DateTime(2023, 6, 22); // end date is after the b-date
        var result3 = Get_Age(start, end);
        var success3 = result3 == 15; // true

        start = new DateTime(2008, 2, 29); // b-date is on feb 29
        end = new DateTime(2023, 2, 28); // end date is before the b-date
        var result4 = Get_Age(start, end);
        var success4 = result4 == 14; // true

        end = new DateTime(2020, 2, 29); // end date is on the b-date, on another leap year
        var result5 = Get_Age(start, end);
        var success5 = result5 == 12; // true
    }
1赞 georgiosd #74

以下是使用手动数学的答案:DateTimeOffset

var diff = DateTimeOffset.Now - dateOfBirth;
var sinceEpoch = DateTimeOffset.UnixEpoch + diff;

return sinceEpoch.Year - 1970;
0赞 Asif Ahmed Sourav #75
static void Main()
{
    DateTime birthday = new DateTime(1990, 5, 15);
    int age = CalculateAge(birthday);
    Console.WriteLine($"The person is {age} years old.");
}

static int CalculateAge(DateTime birthday)
{
    DateTime today = DateTime.Today;
    int age = today.Year - birthday.Year;
    if (birthday > today.AddYears(-age))
    {
        age--;
    }
    return age;
}