16

Having 2 javascript Dates,

first is birthdate and second is a date to calculate age from that date.

What should be the best way to do this.

ArK
  • 20,698
  • 67
  • 109
  • 136
user160820
  • 14,866
  • 22
  • 67
  • 94

14 Answers14

48
function calculateAge (birthDate, otherDate) {
    birthDate = new Date(birthDate);
    otherDate = new Date(otherDate);

    var years = (otherDate.getFullYear() - birthDate.getFullYear());

    if (otherDate.getMonth() < birthDate.getMonth() || 
        otherDate.getMonth() == birthDate.getMonth() && otherDate.getDate() < birthDate.getDate()) {
        years--;
    }

    return years;
}

Example:

var age = calculateAge("02/24/1991", "02/24/2010"); // Format: MM/DD/YYYY
Matt
  • 74,352
  • 26
  • 153
  • 180
  • 7
    To me, this is the most elegant solution. I've always seen programmers stumble over this and resorting to a lot of calculations ... until they realize how people determine how old someone is :) – Ja͢ck May 12 '12 at 08:19
  • 6
    This is definitely the better answer. Any calculation that does math around year-seconds fails to account for the arbitrary nature of dates: laws changing daylight savings, leap years, etc. Let the native Date library deal with that; you really do not want to. Otherwise, be prepared to be wrong by a day or so around their birthday. – Grae Kindel Oct 17 '12 at 16:03
  • 1
    That's the most complete answer. It even handles better leap years. – jdlcgarcia Sep 28 '15 at 15:04
  • Yes when considering age calculation we need to work with years and days and not with ceil and floor values which will incorrectly pushed to wrong values – Juliyanage Silva Feb 11 '20 at 14:16
19

Here is a way:

function getAge(d1, d2){
    d2 = d2 || new Date();
    var diff = d2.getTime() - d1.getTime();
    return Math.floor(diff / (1000 * 60 * 60 * 24 * 365.25));
}
console.log( getAge(new Date(1978, 10, 3)) );

Be careful with the month. Javascript counts them from 0.
1978, 10, 3 means the November 3th, 1978

Mic
  • 24,812
  • 9
  • 57
  • 70
  • 2
    This doesn't properly handle leap years. – jaaksarv May 18 '14 at 14:36
  • @jaaksarv Do you have an example? I assumed the `floor` would shave the differences for most cases. – Mic May 20 '14 at 15:11
  • 2
    console.log( getAge(new Date(2001, 1, 28), new Date(2004, 1, 28)) ); This returns 2, but should return 3. There are tons of examples that do not work. Leap year logic is much more complicated and can't be solved with Floor or other rounding. Much more complicated results are around years 1900 and 2100 that are NOT leap years so there are 7 years with 365 days in a row. – jaaksarv May 21 '14 at 13:18
6
function getAge(dateString) {
  var now = new Date();
  var today = new Date(now.getYear(),now.getMonth(),now.getDate());

  var yearNow = now.getYear();
  var monthNow = now.getMonth();
  var dateNow = now.getDate();

  var dob = new Date(dateString.substring(6,10),
                     dateString.substring(0,2)-1,                   
                     dateString.substring(3,5)                  
                     );

  var yearDob = dob.getYear();
  var monthDob = dob.getMonth();
  var dateDob = dob.getDate();
  var age = {};
  var ageString = "";
  var yearString = "";
  var monthString = "";
  var dayString = "";


  yearAge = yearNow - yearDob;

  if (monthNow >= monthDob)
    var monthAge = monthNow - monthDob;
  else {
    yearAge--;
    var monthAge = 12 + monthNow -monthDob;
  }

  if (dateNow >= dateDob)
    var dateAge = dateNow - dateDob;
  else {
    monthAge--;
    var dateAge = 31 + dateNow - dateDob;

    if (monthAge < 0) {
      monthAge = 11;
      yearAge--;
    }
  }

  age = {
      years: yearAge,
      months: monthAge,
      days: dateAge
      };

  if ( age.years > 1 ) yearString = " years";
  else yearString = " year";
  if ( age.months> 1 ) monthString = " months";
  else monthString = " month";
  if ( age.days > 1 ) dayString = " days";
  else dayString = " day";


  if ( (age.years > 0) && (age.months > 0) && (age.days > 0) )
    ageString = age.years + yearString + ", " + age.months + monthString + ", and " + age.days + dayString + " old.";
  else if ( (age.years == 0) && (age.months == 0) && (age.days > 0) )
    ageString = "Only " + age.days + dayString + " old!";
  else if ( (age.years > 0) && (age.months == 0) && (age.days == 0) )
    ageString = age.years + yearString + " old. Happy Birthday!!";
  else if ( (age.years > 0) && (age.months > 0) && (age.days == 0) )
    ageString = age.years + yearString + " and " + age.months + monthString + " old.";
  else if ( (age.years == 0) && (age.months > 0) && (age.days > 0) )
    ageString = age.months + monthString + " and " + age.days + dayString + " old.";
  else if ( (age.years > 0) && (age.months == 0) && (age.days > 0) )
    ageString = age.years + yearString + " and " + age.days + dayString + " old.";
  else if ( (age.years == 0) && (age.months > 0) && (age.days == 0) )
    ageString = age.months + monthString + " old.";
  else ageString = "Oops! Could not calculate age!";

  return ageString;
}

// A bit of jQuery to call the getAge() function and update the page...
$(document).ready(function() {
  $("#submitDate").click(function(e) {
    e.preventDefault();

    $("#age").html(getAge($("input#date").val()));

  });
});

and HTML IS

Date (MM/DD/YYYY): Calculate Age

Age: 7 years, 1 month, and 15 days old.
Dinesh Rabara
  • 1,119
  • 12
  • 13
  • your code is working but i wonder why. the problem im facing is your constant `31`. a month can contain 28-31 days. but still your code is working. how come ? – Royi Namir May 16 '13 at 12:27
2

Convert the date to milliseconds since the epoch using getTime(), then subtract the values and convert the result back to years:

const MS_PER_YEAR = 1000 * 60 * 60 * 24 * 365.2425;
var years = Math.floor((dateNow.getTime() - dateThen.getTime()) / MS_PER_YEARS);
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
2

Here is one example using moment.js library which is very common now days. Just adding this answer in many of other answers.

var banner = $("#banner-message")
var button = $("button")

// handle click and add class
button.on("click", function(){
  var inputValue = $("#txtInput").val();
  var age = parseInt(moment().diff(inputValue,'years',true));
  
$("#spantext").html(age + ' years.');
  
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#banner-message {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  
  text-align: center;
  transition: all 0.2s;
  margin: 0 auto;
  width: 300px;
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}

#banner-message.alt {
  background: #0084ff;
  color: #fff;
  margin-top: 40px;
  width: 200px;
}

#banner-message.alt button {
  background: #fff;
  color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div id="banner-message">
  <p>Enter Date: <input type='text' id='txtInput' value='1981-12-25' /></p>
  <label>Age is : </label><span id='spantext'></span> <br/>
  <p><button>Calculate Age</button></p>
</div>
vibs2006
  • 6,028
  • 3
  • 40
  • 40
  • Now days I would use `dayjs` as it is smaller and dependency free. API and syntax are mostly the same. – muuvmuuv Oct 21 '19 at 16:01
1

The best way would probably be to convert the date into a timestamp, probably using parse() if the date is a string. Then simply subtracting the numbers and converting the new number back to a date using new Date(milliseconds)

This might not be too accurate for dates before the 1/1/1970 though, so the alternative method of subtracting days, months, etc... separately would be more suitable.

Coin_op
  • 10,568
  • 4
  • 35
  • 46
  • Depending on the accuracy required, this may well be not what is wanted. If it is completed years only (for age) then this is perfectly good. Subtracting dates to get a period is complex - what constitutes a month or a week is very much dependant on the implementation of the conversion back to a date - which will have made its own assumptions as to what constitutes eg a month (30 days; 29 days; 31 days?) As you say dates before 1/1/1970 will be a problem and when calculating ages from birthdates is likely to be a substantial problem (there are more than a few people who are older than 41). – Chris Walton Nov 02 '10 at 09:47
  • Converting the dates into milliseconds since the epoch and subtracting them is the most straightforward and I thought most accurate way to work out differences between dates, but it does have this pre-1970 issue. The browser should automatically take into account days of the month, leap years, etc.... One solution might be to modify the pre 1970 dates with an offset to 1970 before calculating the difference then re-add the offset afterwards. – Coin_op Nov 02 '10 at 09:58
1
var birth = new Date('07/11/2003');
var check = new Date();

var milliDay = 1000 * 60 * 60 * 24; // a day in milliseconds;


var ageInDays = (check - birth) / milliDay;

var ageInYears =  Math.floor(ageInDays / 365 );

example http://www.jsfiddle.net/gaby/XDKa3/1/

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
1

If you are in an huge Javascript project, you maybe [use|need to use] a framework...

With Mootools More, you have a Date Type with a diff method and a timeDiff method that can fit to your needs.

It even provide localisation !

Pascal Qyy
  • 4,442
  • 4
  • 31
  • 46
1

I've modified Mic's response to allow for today being the user's birthday. The difference is the date you're checking the age of should be set to midnight of that day and/or the current date should be set to 23:59:59. An example would be to see if the user is 18 today, this will return 18.

function getAge(d1){
    var now = new Date();
    var d2 = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59);
    var diff = d2.getTime() - d1.getTime();
    return Math.floor(diff / (1000 * 60 * 60 * 24 * 365.25));
}
console.log(getAge(new Date(1992, 10, 17, 0, 0, 0)));
Gary
  • 145
  • 1
  • 2
  • 15
1

This handle leap year use case also:

const getAgeFromBirthDate = (year, month, day) => {
   const date = new Date();
   date.setFullYear(date.getFullYear() - year);
   date.setMonth(date.getMonth() - month);
   //date.setDate(date.getDate() - day);
   return date;
};

console.log( getAgeFromBirthDate(1994, 07, 19).getFullYear() );
M. Hamza Rajput
  • 7,810
  • 2
  • 41
  • 36
1

A simple way to do this is using moment.js.

We have two dates, the birth date (birthDate) and the other date used to calculate age from (specificDate). You can avoid this parameter and get the current age.

moment(specificDate).diff(moment(birthDate), 'years');

Hope it helps you!

Mati Cassanelli
  • 625
  • 6
  • 11
0
function getAge(dateOfBirth, tillDate) {
    var dob = new Date(dateOfBirth);
    var endDt = new Date(tillDate) || new Date();
    return new Date(endDt.getTime() - dob.getTime()).getUTCFullYear() - 1970;
}

Example: console.log(getAge('1/1/2000', '1/1/2016')); // Format: MM/DD/YYYY

Sam G
  • 1,242
  • 15
  • 12
0

Get age calculating by current year

calculateExp(birthDate) {
    birthDate = new Date(birthDate);
    var now = new Date();
    otherDate = new Date(now.getFullYear(),now.getMonth(),now.getDate());
    var years = (otherDate.getFullYear() - birthDate.getFullYear() );


    if (otherDate.getMonth() < birthDate.getMonth() || otherDate.getMonth() == birthDate.getMonth() && otherDate.getDate() < birthDate.getDate()) {
        years--;
    }

    return years;
}
Shemeer M Ali
  • 1,030
  • 15
  • 39
0

This script helps you do the following;

  • Calculate age using start date and end date
  • Determine if year is leap year or not
  • Calculate the number of days in a month
  • Determine if it is an end month
  • Calculate the number of weekends between two dates
  • Determine the next day from a given date

Here is the script; https://github.com/amoschihi/age-calculator

determineAge('2001-01-24','2022-04-03');
  // output: 21 Years, 2 Months and 9 Days
Amos Chihi
  • 375
  • 3
  • 7