Please mind your formatting, don't do it the way you did; just indent your code with 4 spaces using the code (010101) button or Ctrl-K.
–
Marcel KorpelOct 30 '10 at 19:28

I did but it fails to work on IE9 Beta so I had to do it by hand.
–
FranciscOct 31 '10 at 0:04

4

Your original solution is better, at calculating the age, than the current answers. Júlio Santos' answer is essentially the same thing. The other answers give inaccurate results under many conditions, and may be less straightforward or less efficient.
–
Brock AdamsMay 8 '11 at 6:14

Thank you Brock. I was hoping there was a more elegant way of doing this than that which seems a bit crude.
–
FranciscMay 9 '11 at 14:24

3

@Francisc, it is crude, but it's what the Date object would have to do if it encapsulated it. People could write books about the suckiness of JS's Date handling. ... If you can live with sometimes being off by a day, then the approximation: AgeInYears = Math.floor ( (now_Date - DOB_Date) / 31556952000 ) is about as simple as you can get.
–
Brock AdamsMay 9 '11 at 23:19

This returns 0 years for dates like 2000-02-29 to 2001-02-28 when it probably should return 1.
–
RobGMar 21 '14 at 14:13

1

@RobG I don't think a full year technically has passed from 2000-02-29 to 2001-02-28, making your answer invalid. It wouldn't make sense, 2000-02-28 to 2001-02-28 is a year, so 2000-02-29 to 2001-02-28, must be less than a year.
–
André Snede HansenMar 22 '14 at 0:04

1

Lovely answer @AndréSnedeHansen and fast too, since you don't have that crazy division as is present in my answer ;-) +1 for readability and speed.
–
Kristoffer DorphSep 17 '14 at 14:03

Can you give a usage example? I couldn't get it to work without modifying the function to take 3 separate arguments, such as: getAge(y,m,d). For example: jsbin.com/ehaqiw/1/edit
–
edtApr 15 '13 at 4:20

Interesting that this is slower than the OP's original code...
–
staticxJan 28 '14 at 16:26

@André Snede Hansen: I did not see a better answer.
–
naveenFeb 25 '14 at 7:55

Naveen, I returned to the answer, and realized that my answer is not accurate, and would agree that your answer is both the fastest and the most reliable.
–
André Snede HansenMar 3 '14 at 13:15

@AndréSnedeHansen, your answer was magic. i loved it. I am sorry about reverting your edit. see, when i wrote that, there were no better answers, you see.. sorry if i hurt you brother.
–
naveenMar 3 '14 at 13:45

Important: This answer doesn't provide an 100% accurate answer, it is off by around 10-20 hours depending on the date.

There are no better solutions ( not in these answers anyway ). - naveen

I of course couldn't resist the urge to take up the challenge and make an faster and shorter birthday calculator than the current accepted solution.
The main point for my solution, is that math is fast, so instead of using branching, and the date model javascript provides to calculate a solution we use the wonderful math

The answer looks like this, and runs ~65% faster than naveen's plus it's much shorter:

The magic number: 31557600000 is 24 * 3600 * 365.25 * 1000
Which is the length of a year, the length of a year is 365 days and 6 hours which is 0.25 day. In the end i floor the result which gives us the final age.

This answer has a bug in it. Set your clock to 12:01am. At 12:01am, if you calcAge('2012-03-27') (today's date) you will get an answer of zero, even though it should equal 1. This bug exists for the entire 12:00am hour. This is due to the incorrect statement that a year has 365.25 days in it. It does not. We are dealing with calendar years, not the length of the Earth's orbit (which is more accurately 365.256363 days). A year has 365 days, except a leap year which has 366 days. Besides that, performance on something like this is meaningless. Maintainability is far more important.
–
Eric BrandelMar 27 '13 at 17:57

This gives invalid values for select date combinations! For example, if the birthDate is Jan 5th, 1980, and the current date is Jan 4th, 2005, then the function will erroneously report age as 25... The correct value being 24.
–
Brock AdamsMay 8 '11 at 5:09

@BrockAdams Why is this? I am having this problem at the moment. Thanks.
–
VisionIncisionDec 4 '11 at 19:16

@VisionIncision, because it does not handle edge conditions properly. Believe it or not, the code from the question is the best approach -- although it looks like one of the later answers might have repackaged it more suitably.
–
Brock AdamsDec 4 '11 at 20:22

CMS Hi :-) I wrote this question (stackoverflow.com/questions/16435981/…) and I was told that if i want 100% accurate answer i should check every year - if it is a leap year , and then calc the last fraction. (see Guffa's answer). Your function (part of it) does that. but how can I use it to calc the age 100% accurate ? the DOB rarely begins at 1/1/yyyy..... so how can i use your func to calc the exact age ?
–
Royi NamirMay 11 '13 at 8:48

This gives inaccurate results in leap-years, for birthdays after Feb 28th. It ages such people by 1 day. EG: for DoB = 2001/07/04, this function will return 7 years, on 2008/07/03.
–
Brock AdamsMay 8 '11 at 5:56

Yes, I think you might have (haven't rigorously tested, just analyzed). But, notice that the new solution is no simpler and no more elegant than the OP's solution (not counting that this one is properly encapsulated in a function). ... The OP's solution is easier to understand (thus to audit, to test or to modify). Sometimes simple and straightforward is best, IMO.
–
Brock AdamsMay 9 '11 at 23:33

@Brock: I fully agree: I have to think about what this function does and that's never a good thing.
–
Marcel KorpelMay 10 '11 at 8:00

Shouldn't "if (doyNow < doyBirth)" be "if (doyNow <= doyBirth)" ? In all my tests, the day has been off by one and that fixed it.
–
Ted KulpJul 25 '11 at 16:53

I just had to write this function for myself - the accepted answer is fairly good but IMO could use some cleanup. This takes a unix timestamp for dob because that was my requirement but could be quickly adapted to use a string:

1) Take the year difference of date one and date two. Save the year difference in Y. Example 2015 - 2013 = 2.

2) Take the month difference of date one and date two. If difference is positive or zero save the month difference in M. If difference is negative then change Y to Y-1 and then add 12 to second date's month, subtract it from first date's month and save it in M.

3) Take the days difference of date one and date two. If difference is positive or zero save it to D. If difference is negative then change M to M-1 and find out number of days in that particular month (28, 29, 30 or 31) and add that to the value and then go for subtraction. Save the value in D.

All the answers I tested here (about half) think 2000-02-29 to 2001-02-28 is zero years, when it most likely should be 1 since 2000-02-29 to 2001-03-01 is 1 year and 1 day. Here is a getYearDiff function that fixes that. It only works where d0 < d1:

I don't think a full year technically has passed from 2000-02-29 to 2001-02-28, making your answer invalid. It wouldn't make sense, 2000-02-28 to 2001-02-28 is a year, so 2000-02-29 to 2001-02-28, must be less than a year.
–
André Snede HansenMar 22 '14 at 0:07

1

"Technically"? It is purely an administrative thing, the there are probably as many places that go for 1 March as 28 Feb. So there is need for a choice that no one else thought to do.
–
RobGMar 22 '14 at 8:27

It's definetely not an "administrative thing", its purely defined in time specifications, which I am not going to dig through.
–
André Snede HansenMar 22 '14 at 22:04

@AndréSnedeHansen—if you create a Date for 2000-02-29 and add one year using setDate(getDate + 1) you'll get 2001-03-01. But that is a choice of the javascript authors based on what Java does, similar to how the default toString returns dates in month, day, year order, which is inconsistent with the vast majority of administrative systems. Do some research into how different places treat leap years and durations.
–
RobGJan 6 at 6:10