我如何用C#计算某人的年龄?

给定代表一个人的生日的 DateTime ,我如何计算他们年龄的年龄?

0
额外 编辑
意见: 23
@Yaur:只需将现在+出生时间转换为GMT / UTC,年龄只是一个相对值,因此时区是无关紧要的。要确定用户当前的时区,可以使用GeoLocating。
额外 作者 Stefan Steiger,
为什么不考虑[Julian Date] [1]? [1]: stackoverflow.com/questions/7103064/…
额外 作者 Muhammad Hewedy,
到目前为止所有答案都错过了,它取决于人们出生在哪里以及他们现在在哪里。
额外 作者 Yaur,
请注意,对于不到一岁的人,他们的年龄以几天,几周或几个月为单位。单位的过渡时间可能是特定于域的。
额外 作者 Andrew Morton,
为什么没有人使用TimeSpan?
额外 作者 Arijit Mukherjee,
如果我们考虑@Yaur对跨时区计算的建议,Day Daylight Time是否应以任何方式影响计算?
额外 作者 DDM,
没有人考虑过闰年?或检查月份?
额外 作者 Crash Override,

7 答案

很多年前,为了在我的网站上提供一个年龄计算器噱头,我写了一个函数来计算年龄分数。这是C#的一个快速端口(来自 PHP版本)。恐怕我没有能够测试C#版本,但希望你也能享受到这一切!

(不可否认,这对于在Stack Overflow中显示用户配置文件有点噱头,但是读者也许会发现它的一些用处:-))

double AgeDiff(DateTime date1, DateTime date2) {
    double years = date2.Year - date1.Year;

    /*
     * If date2 and date1 + round(date2 - date1) are on different sides
     * of 29 February, then our partial year is considered to have 366
     * days total, otherwise it's 365. Note that 59 is the day number
     * of 29 Feb.
     */
    double fraction = 365
            + (DateTime.IsLeapYear(date2.Year) && date2.DayOfYear >= 59
            && (date1.DayOfYear < 59 || date1.DayOfYear > date2.DayOfYear)
            ? 1 : 0);

    /*
     * The only really nontrivial case is if date1 is in a leap year,
     * and date2 is not. So let's handle the others first.
     */
    if (DateTime.IsLeapYear(date2.Year) == DateTime.IsLeapYear(date1.Year))
        return years + (date2.DayOfYear - date1.DayOfYear) / fraction;

    /*
     * If date2 is in a leap year, but date1 is not and is March or
     * beyond, shift up by a day.
     */
    if (DateTime.IsLeapYear(date2.Year)) {
        return years + (date2.DayOfYear - date1.DayOfYear
                - (date1.DayOfYear >= 59 ? 1 : 0)) / fraction;
    }

    /*
     * If date1 is not on 29 February, shift down date1 by a day if
     * March or later. Proceed normally.
     */
    if (date1.DayOfYear != 59) {
        return years + (date2.DayOfYear - date1.DayOfYear
                + (date1.DayOfYear > 59 ? 1 : 0)) / fraction;
    }

    /*
     * Okay, here date1 is on 29 February, and date2 is not on a leap
     * year. What to do now? On 28 Feb in date2's year, the ``age''
     * should be just shy of a whole number, and on 1 Mar should be
     * just over. Perhaps the easiest way is to a point halfway
     * between those two: 58.5.
     */
    return years + (date2.DayOfYear - 58.5) / fraction;
}
0
额外
这很酷。虽然我只是用了天文数年。
额外 作者 IllidanS4,

我知道的最好的方式是因为闰年和一切:

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

希望这可以帮助。

0
额外

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

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,

我不认为迄今为止的答案提供了不同年龄的文化。例如,参见东亚年龄清算与西方国家相比。

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

0
额外
@some - 韩国人仍然主要使用这个系统。
额外 作者 Justin L.,
其实这个概念可能非常重要 - 人们不喜欢被错误地告知他们的个人信息。举个例子,我家有一半人住在马来西亚,一半住在英国。现在,我与家人的一方比另一方的年龄高两岁。
额外 作者 Phil Gan,
从您提供的维基百科文章中可以看出:“在中国和日本,它被用于传统的算命或宗教信仰,而且它在城市人民之间的日常生活中正在消失。”
额外 作者 some,
不仅我们这个系统主要用于韩国,而且作为一个与当地人讨论年龄的旅游者,当地人在他们出生的那一年会礼貌地互相提及自己。我不是25岁,我是87岁。我更喜欢这种方法。更多的是“国际出生时间格式”
额外 作者 Dean Rather,
即使在韩国,虽然这种系统广泛用于休闲对话,但出于法定目的(例如饮酒年龄),西方推算被使用。所以我认为只是翻转文化开关是做一些你不打算做的事情的好方法。
额外 作者 Casey,

这是一种很奇怪的方法,但如果您将日期格式设置为 yyyymmdd ,并从当前日期中减去出生日期,那么删除最后4位数字即可获得年龄:)

我不知道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;
}
0
额外
最好添加一个参数:float.Parse(x,CultureInfo.InvariantCulture),因为一些本地人使用逗号而不是小数点作为分隔符中的分隔符
额外 作者 krvladislav,
询问非常旧的帖子 int age =(now - dob)/ 10000; 为什么你减去10000?
额外 作者 Monojit Sarkar,
DateTime.MaxValue年是9999,MinValue年是1,溢出是不可能的。
额外 作者 Antonín Lejsek,
实际上,这对使用带有日期时间字段的MS-SQL非常有用(自01-011900以来的总天数)
额外 作者 Patrik Eckebrecht,
@numerek请将您的建议修改作为自己的答案。对于什么是值得的,当前的10000次是远不及整数溢出的两个数量级。 20,150,000比2,147,483,648
额外 作者 GalacticCowboy,
Horray用于 yyyymmdd 。我在一台 P>个人计算机(大约1981年)上使用的第一个数据库产品以这种格式存储日期。任何类型的日期操作都非常容易。
额外 作者 radarbob,
在你的备用答案中,可以通过减去年份然后减去月份* 30.5 +天并除以366来避免整数溢出
额外 作者 numerek,
这个答案假设闰日婴儿在非闰年的3月1日有他们的生日。
额外 作者 Jamie Kitson,

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

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

不过,这假定您正在寻找西方的年龄理念,而不是使用 东亚推算

0
额外
@JAG:DateTime.Today应该更快。
额外 作者 Shimmy,
此代码不计算最近的年龄。这里是代码:var ts = DateTime.Now - new DateTime(1988,3,19); var age = Math.Round(ts.Days / 365.0);
额外 作者 Dhaval Panchal,
我不能编辑我的评论了,所以这里是我的更正: TimeSpan difference = subject.Birthday - DateTime.Now; int age = difference.Days; 如果你想要年龄,你总是可以添加 int ageInYears = age / 365;
额外 作者 Nolonar,
这样做会不会更容易 DateTime dateDifference = subject.Birthday - DateTime.Now; int age = dateDifference.Year; ?另外,我不认为年龄取决于闰年。毕竟,一年定义为365 <366天,闰年不会让你更加年轻。
额外 作者 Nolonar,
或者只是如果(BirthDate.DayOfYear> Today.DayOfYear);不需要修改日期变量
额外 作者 NKCSS,
@Danvil,它真的错了吗?举一个更简单的例子。生日= 2000/02/29,今天= 2001/02/28。过去的日子:365.那不是一年,因此,28日不是一岁的人吗?或者是一年365-1 / 4天的定义?我只是在说,这很复杂。
额外 作者 devuxer,
最后一行让我觉得太多了。取而代之的是:if(bday.AddYears(age)> now)age--;这似乎是一个更直观的表达。
额外 作者 cdiggins,
衡量年龄的概念只是一个肮脏的谎言,因为它没有考虑闰年。我们应该以天测量年龄。
额外 作者 Melbourne Developer,
@Legends它的回答中提出了比假设更多的假设,对于你的情况,只有这些假设适合你的情况才是正确的。如果不知道你的情况,除了你自己以外,任何人都不可能将其转化为是或否的答案。
额外 作者 hvd,
@ LukeTO'Brien if(bday> today.AddYears(-age))age - ; 在这个答案中的一部分应该照顾到这一点。根据年份数的差异, age 将在 10 处。如果生日(1990年12月)晚于10年前(即1990年3月),那么 age 会减少到 9 。你是说这对你不起作用吗?
额外 作者 hvd,
这个解决方案上面有超过1400个正确的提议,因为我可以从评论部分阅读,这个解决方案有一些问题......?
额外 作者 Legends,
这个答案不需要考虑月份 - 如果我出生于1990年12月,今天是2000年3月,我的年龄是9岁而不是10岁,因为我还没有过我的生日
额外 作者 Luke T O'Brien,
所以我们根据不同的国家和日历有不同的年龄?什么一勺...
额外 作者 e-satis,
@LarsD“当前活着的人出生后,有几个国家已经跳过日期”< - 你是什么意思?
额外 作者 cja,
@Rob我想你是对的,但这是一个精确的问题,通常你的生日会在特定的一天的00:00 - 23:59:59之间。
额外 作者 Tristan Warner-Smith,
鉴于我们正在谈论生日,您可以使用DateTime.Today,因为时间部分没有相关性。
额外 作者 Tristan Warner-Smith,
快速有趣的事实:此答案已在此 pluralsight course ,第5单元 - 第3章。
额外 作者 displayName,
这个解决方案是否也在寻找几个月?否则它会变成+/- 1年
额外 作者 alpham8,
@cja - 这意味着一些国家在几年前就开始使用一些流氓软件来同步日历并消除差异! en.wikipedia.org/wiki/Gregorian_calendar 可能会讲更多关于它,我还没有完全读。提到'现在的人'只是简单地说,调整发生在20世纪(1901年至2000年)。从那个时期开始,很多人还活着! :)
额外 作者 bPratik,
为什么不使用 TimeSpan
额外 作者 gldraphael,
@NKCSS:这不能正确处理闰年。我的测试表明只有 if(bday> now.AddYears(-age))有效。由于 DayOfYear 在2012年返回 61 ,2011年3月1日返回 60
额外 作者 Guvante,
此答案不适用于所有地区和所有年龄段。在俄罗斯(1918年),希腊(1924年)和土耳其(1926年)等当前活生人诞生后,有几个国家的日期略有不同。
额外 作者 Lars D,
@LarsD所以你说的是没有办法计算人的年龄?垃圾。他们与日历搞砸了,他们可以适应。即使你可以做一个图书馆来计算基于区域的交叉日历,a)你从哪里获得这个信息?b)它实际上值得吗?
额外 作者 Gusdor,
@ TristanWarner-Smith从技术上来说,它确实如此。如果你是在1990年1月1日下午1点出生的,那么你在1991年1月1日12:59时是0,但是在1991年1月1日下午1:01时是1。
额外 作者 Rob,
DateTime birthdate = new DateTime(2012,11,5); DateTime now = DateTime.Now; int年=现在。年 - birthdate.Year; if(now.Month
额外 作者 Shaik Raffi,
在英格兰和威尔士或香港,2月29日出生的人将于3月1日合法地到达18岁。如果他或她在台湾出生,他或她在2月28日前合法地成为18岁。( Wikipedia )所以 birthdate.AddYears(age) >今天birthdate> today.AddYears(-age)都是正确和不正确的,具体取决于管辖权。
额外 作者 Daniel Liuzzi,
只想对DateTime.Now表现发表评论。如果你不需要一个准确的时区值,使用DateTime.UtcNow它更快。
额外 作者 JAG,
int age = DateTime.Today.Year - bday.Year; age = bday> DateTime.Today.AddYears(-age))?年龄 - :年龄;
额外 作者 Travis,
好主意cdiggins,但它不工作作为bday.AddYears(年龄)当年龄是2/29返回2/28年不是闰年...继续尝试
额外 作者 Mike Polen,
事实上,它仍然不完全正确。此代码假定'bday'是日期时间的日期部分。这是一个边缘案例(我想大多数人只会通过日期而不是日期),但是如果您将生日作为时间大于00:00:00的日期和时间传递,会碰到Danvil指出的错误。设置bday = bday.Date修复了这个问题。
额外 作者 Øyvind,
@Rob在美国,至少,可以接受的是,在你的生日当天,无论你出生的那一天是什么时候,你都会被认为是年后的下一个年龄段。即使有人出生于1月1日晚上11:59,在新年派对上球落下时,即使你的出生时间还差不多24小时,每个人都会接受你的年龄有所改变。 :)从法律上讲,一个人在他们的生日也被认为是年纪大一岁。无论是开车16次,喝酒21次,还是18次投票。不管你出生在什么时候。在你的生日那天,你比你大一岁。
额外 作者 jfren484,
您的最后一个情况birthdate> now.AddYears(-age)是我迅速因为您的帖子而得到的东西!非常感谢
额外 作者 Avdhut Vaidya,

这是我们在这里使用的版本。它可以工作,而且非常简单。这与Jeff的想法是一样的,但我认为它更清晰一些,因为它将逻辑减去1,所以它更容易理解。

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

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

很明显,这是在 DateTime 上作为扩展方法完成的,但显然你可以抓住那行代码来完成工作并将它放在任何地方。这里我们有另一个重载的扩展方法,它传入 DateTime.Now ,仅仅为了完整性。

0
额外
我认为当dayOfBirth或dateAsAt中的某一个出现在闰年中时,这可以关闭一天。考虑2004年2月29日出生于2003年3月1日的人的年龄。为了纠正这种情况,您需要对(Month,DayOfMonth)对进行字典对比并将其用于条件。
额外 作者 Doug McClean,
它也不会显示你的生日的正确年龄。
额外 作者 dotjoe,