标签云

微信群

扫码加入我们

WeChat QR Code


what all of the answers so far have missed is that it depends where the person was born and where they are right now.

2018年12月11日01分43秒

Yaur: Just convert the time of now + birth into GMT/UTC, age is only a relative value, hence timezones are irrelevant. For determining the user's current timezone, you can use GeoLocating.

2018年12月11日01分43秒

Why not consider [Julian Date][1]? [1]: stackoverflow.com/questions/7103064/…

2018年12月11日01分43秒

If we're taking into consideration Yaur 's suggestion of cross-timezone calculations, should Day Light Saving Time affect the calculation in any manner?

2018年12月11日01分43秒

No one has considered leap years? or checking the month?

2018年12月11日01分43秒

Just wanted to comment on DateTime.Now performance. If you don't need an accurate time zone value, use DateTime.UtcNow it's much faster.

2018年12月11日01分43秒

Given we're talking birthdays you can just use DateTime.Today given the time part has no relevance.

2018年12月11日01分43秒

This answer does not work with all locales and all ages. Several countries have skipped dates after the birth of current living people, including Russia (1918), Greece (1924) and Turkey (1926).

2018年12月11日01分43秒

Actually, it's still not entirely correct. This code presumes that 'bday' is the date-portion of a DateTime. It's an edge-case (I guess most people will just be passing dates and not date-times), but if you pass in a birthday as a date-and-time where the time is greater than 00:00:00 then you'll run into the bug Danvil pointed out. Setting bday = bday.Date fixes this.

2018年12月11日01分43秒

The last line made me think too much. Instead how about: if (bday.AddYears(age) > now) age--; This seems to be a more intuitive expression.

2018年12月11日01分43秒

Horray for yyyymmdd. The 1st database product I used on a Personal Computer (circa 1981) stored dates in this format. Date manipulation of any kind was so much easier.

2018年12月11日01分43秒

Actually this is great for usage on MS-SQL with datetime-fields (total days since 01-011900)

2018年12月11日01分43秒

numerek Please post your suggested modifications as their own answer. For what it's worth, the current year times 10000 is nowhere near an integer overflow, by two orders of magnitude. 20,150,000 vs 2,147,483,648

2018年12月11日01分43秒

LongChalk 20180101 - 20171231 = 8870. Drop the last 4 digits and you have (an implied) 0 for the age. How did you get 1?

2018年12月11日01分43秒

flindeberg Yeah, that's what I was saying to LongChalk...

2018年12月11日01分43秒

Output was -Test 9 9 8

2018年12月11日01分43秒

While this code works, it asserts that a person born on a leap day attains the next year of age on March 1st on non-leap years, rather than on February 28th. In reality, either option may be correct. Wikipedia has something to say about this. So while your code is not "wrong", neither is the accepted solution.

2018年12月10日01分43秒

MattJohnson I think that's actually correct. If my bday was Feb 29, then Feb 28 my bday hasn't passed, and I should still be the same age as on Feb 27. On March 1, however, we have passed my bday and I should be the next age. In the US, a business that sells alcohol will have a sign that says something like "If you were born after this day in YYYY, you can't purchase alcohol" (where YYYY changes every year). That means that someone born on Feb 29 cannot buy alcohol on Feb 28 in the year they turn 21 (most places), and lends support to the idea that they are not a year older until March 1.

2018年12月11日01分43秒

jfren484 - read the Wikipedia article. It varies considerably across jurisdictions.

2018年12月11日01分43秒

jfren484 Your claim has absolutely nothing to do with philosophy; but everything to do with your own personal feeling. When a person born on 29 Feb "ages" is largely unimportant unless the age forms a 'legal age boundary' (e.g. Can buy alcohol, vote, get pension, join army, get driving license). Consider US drinking age (21 years): For most people that's 7670 days. It's 7671 days if born before 29 Feb in leap year or from 1 Mar before leap year. If born on 29 Feb: 28 Feb is 7670 days and 1 Mar is 7671 days. The choice is arbitrary it can go either way.

2018年12月11日01分43秒

From the wikipedia article that you provided: "In China and Japan it is used for traditional fortune-telling or religion, and it is disappearing in daily life between peoples in the city."

2018年12月10日01分43秒

some -- Koreans still use this system primarily.

2018年12月11日01分43秒

Actually this concept can be pretty important - people don't like being told their personal information incorrectly. As an example, half of my family lives in Malaysia and half in the UK. Right now my age is considered two years higher when I'm with one side of my family than with the other.

2018年12月11日01分43秒

Not only us this system used primarily in Korea, but as a tourist discussing ages with locals, locals will politely refer to yourself an each other by their birth year. I'm not 25, I'm 87. I like this approach better. more of an 'international birthdatetime format'

2018年12月11日01分43秒

In Vietnam, in daily life even when Western system is used, age is calculated merely by subtracting the years. Date is excluded

2018年12月11日01分43秒

A comment regarding having the 29th Feb birthday on 1st March, technically, having it on the 28th is too early (1 day early in fact). On the 1st is one day too late. But since the birthday is between, using the 1st to calculate the age in non-leap years makes more sense to me, since that person is indeed that old on March 1st (and 2nd and 3rd) every year, but not on Feb 28th.

2018年12月11日01分43秒

Where does 365.255 come from? I don't think this will work in general.

2018年12月11日01分43秒

365 for the days in a year. +0.25 for leap years. +0.005 for other corrections

2018年12月11日01分43秒

I don't think Harry Patch would have appreciated your spot-testing methodology: latimes.com/news/obituaries/…

2018年12月11日01分43秒

The average length of a year in the Gregorian Calendar is 365.2425 days.

2018年12月11日01分43秒

^^ Because sometimes it's important. In my testing this fails on the persons birthday, it reports them younger than they are.

2018年12月11日01分43秒

This appears to handle different regions (date formats) the best.

2018年12月11日01分43秒

This is broken. Made testable: public static int CalculateAge(DateTime dateOfBirth, DateTime dateToCalculateAge) { return new DateTime(dateToCalculateAge.Subtract(dateOfBirth).Ticks).Year - 1; } ...Gives age 14 when I input 1990-06-01 and calculate the age on the day BEFORE his 14th birthday (1990-05-31).

2018年12月11日01分43秒

I think this can be off by one day when exactly one of dateOfBirth or dateAsAt falls in a leap year. Consider the age of a person born on March 1, 2003 on February 29, 2004. To rectify this, you need to do a lexicographic comparison of (Month, DayOfMonth) pairs and use that for the conditional.

2018年12月11日01分43秒

it's also not going to show the right age as of your birthday.

2018年12月11日01分43秒

This does not work all the time. Adding a Span to the DateTime.MinValue could work boes this does not account for leap years etc. If you add the Years, months and days to Age using the AddYears(), AddMonths and AddDays() function it will not always return the Datetime.Now date.

2018年12月11日01分43秒

timespan itself automatically takes into account leap years between 2 dates so I'm not sure what your getting on about. I have asked on microsoft forums and microsoft has confirmed it takes into account leap years between 2 dates.

2018年12月11日01分43秒

Consider the following TWO senarios. 1st DateTime.Now is 1/1/2001 and a child is born on 1/1/2000. 2000 is a leap year and the result will be 1years, 0 months and 1 days. In the second senarion DateTime.Now is 1/1/2002 and the child is born on 1/1/2001. In this case the result will be 1 years, 0 months and 0 days. That will happen because you are adding the timespan on a non-leap year. If DateTime.MinValue was a leap year then the results would be 1 year at the first and 0 years 11 months and 30 days. (Try it in your code).

2018年12月11日01分43秒

Upvote! I came up with a solution that is pretty much identical (I used DateTime.MinValue.AddTicks(span.Ticks) instead of +, but the result is the same and yours has a few characters less code).

2018年12月11日01分43秒

You are quite right it's not. But IF it was that would be the result. Why does it matter? It doesn't. In either case leap or not then there are examples where this does not work. That was what I wanted to show. The DIFF is correct. Span takes into account leap years. But ADDING to a base date is not. Try the examples in code and you will see I'm right.

2018年12月11日01分43秒

I stumbled into this long and annoying discussion, and your solution is a really nice and small approach. Thanks for keeping it simple

2018年12月11日01分43秒

TimeSpan was my first choice, but found that it doesn't offer a TotalYears property. You could try (ts.TotalDays / 365) - but it doesn't account for leap years etc.

2018年12月11日01分43秒

With string concat, this would be possible: 47 Yrs 11 Mo 7 days

2018年12月11日01分43秒