77

I want to get the number of years between two dates. I can get the number of days between these two days, but if I divide it by 365 the result is incorrect because some years have 366 days.

This is my code to get the difference between the dates:

var birthday = value;//format 01/02/1900
var dateParts = birthday.split("/");

var checkindate = new Date(dateParts[2], dateParts[0] - 1, dateParts[1]);   
var now = new Date();
var difference = now - checkindate;
var days = difference / (1000*60*60*24);

var thisyear = new Date().getFullYear();
var birthyear = dateParts[2];

    var number_of_long_years = 0;
for(var y=birthyear; y <= thisyear; y++){   

    if( (y % 4 == 0 && y % 100 == 0) || y % 400 == 0 ) {
    
                    number_of_long_years++;             
    }
}   

The day count works perfectly. I am trying to do add the additional days when it is a 366-day year, and I'm doing something like this:

var years = ((days)*(thisyear-birthyear))
            /((number_of_long_years*366) + ((thisyear-birthyear-number_of_long_years)*365) );

I'm getting the year count. Is this correct, or is there a better way to do this?

Kanishka Panamaldeniya
  • 17,302
  • 31
  • 123
  • 193
  • Could this work? http://www.datejs.com/ – Christian Wattengård Nov 16 '11 at 13:29
  • 5
    This is **javascript** not **[jquery](http://jquery.com)** – Matt Nov 16 '11 at 13:29
  • Possible Duplicate http://stackoverflow.com/questions/1914186/how-to-calculate-years-and-months-between-two-dates-in-javascript – Sai Kalyan Kumar Akshinthala Nov 16 '11 at 13:35
  • If you are using moment /** * Convert date of birth into age * param {string} dateOfBirth - date of birth * param {string} dateToCalculate - date to compare * returns {number} - age */ export const getAge = (dateOfBirth, dateToCalculate) => { const dob = moment(dateOfBirth); return moment(dateToCalculate).diff(dob, 'years'); }; – Shyam Kumar Sep 24 '19 at 17:16

25 Answers25

105

Sleek foundation javascript function.

 function calculateAge(birthday) { // birthday is a date
   var ageDifMs = Date.now() - birthday;
   var ageDate = new Date(ageDifMs); // miliseconds from epoch
   return Math.abs(ageDate.getUTCFullYear() - 1970);
 }
testUserPleaseIgnore
  • 1,059
  • 2
  • 7
  • 2
  • 1
    I tried your solution, but when I used a birthday that was on the same day one year prior, it said the age was 0 when it should be 1. – tronman Jul 10 '15 at 15:54
  • 11
    It's not necessarily wrong, because the same day one year later is not a full year - it only is if the birthday date has a time of 00:00:00, and the current date time is 24:00:00 on the same day - which is 00:00:00 of the **following day**! Thus, you might wanna add one day to ageDate before you continue. I would `setHours(0,0,0,0)` on birthday still, because I anticipate trouble if it it's > 0 and some crazy DST / leap year / timezone changes are involved. Or `setHours(24, 0, 0, 0)` on the birthday maybe? Better test it thoroughly. – CodeManX Sep 01 '15 at 21:21
  • 3
    This will have occasional issues with leap years as it effectively assumes everyone was born on 1 Jan 1970. – RobG Sep 10 '20 at 22:19
  • @CodeManX when calculating age we would say someone is +1 years older when their birthday begins so in this context it is wrong. Easier solution is to add (1000 * 60 * 24) to `ageDifMs` and let date library take care of everything else – ICW Jun 01 '22 at 16:23
28

Probably not the answer you're looking for, but at 2.6kb, I would not try to reinvent the wheel and I'd use something like moment.js. Does not have any dependencies.

The diff method is probably what you want: http://momentjs.com/docs/#/displaying/difference/

Leo
  • 5,069
  • 2
  • 20
  • 27
  • 2
    I want to point out that moment.js' base code and algoritm hasn't changed from 2011. Even though the state of browsers and their JS support is very different now. Moment.js' creators themselves suggested people to use Luxon if you are a new adopter. – Daniel Wu Apr 29 '22 at 03:28
  • See this answer about using date-fn. also recommended by momentJS. https://stackoverflow.com/a/76637004/12624118 – yoty66 Jul 07 '23 at 12:31
20

Using pure javascript Date(), we can calculate the numbers of years like below

document.getElementById('getYearsBtn').addEventListener('click', function () {
  var enteredDate = document.getElementById('sampleDate').value;
  // Below one is the single line logic to calculate the no. of years...
  var years = new Date(new Date() - new Date(enteredDate)).getFullYear() - 1970;
  console.log(years);
});
<input type="text" id="sampleDate" value="1980/01/01">
<div>Format: yyyy-mm-dd or yyyy/mm/dd</div><br>
<button id="getYearsBtn">Calculate Years</button>
Sivakumar Tadisetti
  • 4,865
  • 7
  • 34
  • 56
  • It's working most of the times but it looks like if someone is born on the 2005/10/26 or the 2004/10/26 when the computer date is set to 2019/10/26 the functions returns both of the times 14. Does anyone know why? – DadiBit Oct 26 '19 at 16:54
15

No for-each loop, no extra jQuery plugin needed... Just call the below function.. Got from Difference between two dates in years

function dateDiffInYears(dateold, datenew) {
    var ynew = datenew.getFullYear();
    var mnew = datenew.getMonth();
    var dnew = datenew.getDate();
    var yold = dateold.getFullYear();
    var mold = dateold.getMonth();
    var dold = dateold.getDate();
    var diff = ynew - yold;
    if (mold > mnew) diff--;
    else {
        if (mold == mnew) {
            if (dold > dnew) diff--;
        }
    }
    return diff;
}
kiner_shah
  • 3,939
  • 7
  • 23
  • 37
Paritosh
  • 11,144
  • 5
  • 56
  • 74
8

I use the following for age calculation.

I named it gregorianAge() because this calculation gives exactly how we denote age using Gregorian calendar. i.e. Not counting the end year if month and day is before the month and day of the birth year.

/**
 * Calculates human age in years given a birth day. Optionally ageAtDate
 * can be provided to calculate age at a specific date
 *
 * @param string|Date Object birthDate
 * @param string|Date Object ageAtDate optional
 * @returns integer Age between birthday and a given date or today
 */
gregorianAge = function(birthDate, ageAtDate) {
  // convert birthDate to date object if already not
  if (Object.prototype.toString.call(birthDate) !== '[object Date]')
    birthDate = new Date(birthDate);

  // use today's date if ageAtDate is not provided
  if (typeof ageAtDate == "undefined")
    ageAtDate = new Date();

  // convert ageAtDate to date object if already not
  else if (Object.prototype.toString.call(ageAtDate) !== '[object Date]')
    ageAtDate = new Date(ageAtDate);

  // if conversion to date object fails return null
  if (ageAtDate == null || birthDate == null)
    return null;


  var _m = ageAtDate.getMonth() - birthDate.getMonth();

  // answer: ageAt year minus birth year less one (1) if month and day of
  // ageAt year is before month and day of birth year
  return (ageAtDate.getFullYear()) - birthDate.getFullYear()
    - ((_m < 0 || (_m === 0 && ageAtDate.getDate() < birthDate.getDate()))?1:0)
}
<input type="text" id="birthDate" value="12 February 1982">
<div style="font-size: small; color: grey">Enter a date in an acceptable format e.g. 10 Dec 2001</div><br>
<button onClick='js:alert(gregorianAge(document.getElementById("birthDate").value))'>What's my age?</button>
nazim
  • 1,439
  • 2
  • 16
  • 26
5

Little out of date but here is a function you can use!

function calculateAge(birthMonth, birthDay, birthYear) {
    var currentDate = new Date();
    var currentYear = currentDate.getFullYear();
    var currentMonth = currentDate.getMonth();
    var currentDay = currentDate.getDate(); 
    var calculatedAge = currentYear - birthYear;

    if (currentMonth < birthMonth - 1) {
        calculatedAge--;
    }
    if (birthMonth - 1 == currentMonth && currentDay < birthDay) {
        calculatedAge--;
    }
    return calculatedAge;
}

var age = calculateAge(12, 8, 1993);
alert(age);
Oliver Olding
  • 41
  • 1
  • 8
Jim Vercoelen
  • 1,048
  • 2
  • 14
  • 40
4

You can get the exact age using timesstamp:

const getAge = (dateOfBirth, dateToCalculate = new Date()) => {
    const dob = new Date(dateOfBirth).getTime();
    const dateToCompare = new Date(dateToCalculate).getTime();
    const age = (dateToCompare - dob) / (365 * 24 * 60 * 60 * 1000);
    return Math.floor(age);
};
grrigore
  • 1,050
  • 1
  • 21
  • 39
Shyam Kumar
  • 586
  • 3
  • 17
4
let currentTime = new Date().getTime();
let birthDateTime= new Date(birthDate).getTime();
let difference = (currentTime - birthDateTime)
var ageInYears=difference/(1000*60*60*24*365)
Ehasanul Hoque
  • 578
  • 8
  • 14
  • 3
    While this code may resolve the OP's issue, it is best to include an explanation as to how your code addresses the OP's issue. In this way, future visitors can learn from your post, and apply it to their own code. SO is not a coding service, but a resource for knowledge. Also, high quality, complete answers are more likely to be upvoted. These features, along with the requirement that all posts are self-contained, are some of the strengths of SO as a platform, that differentiates it from forums. You can edit to add additional info &/or to supplement your explanations with source documentation. – ysf Jun 14 '20 at 20:08
  • This is flawed because of leap years. – basbase Jan 10 '22 at 09:37
3
getYears(date1, date2) {
let years = new Date(date1).getFullYear() - new Date(date2).getFullYear();
let month = new Date(date1).getMonth() - new Date(date2).getMonth();
let dateDiff = new Date(date1).getDay() - new Date(date2).getDay();
if (dateDiff < 0) {
    month -= 1;
}
if (month < 0) {
    years -= 1;
}
return years;
}
  • The only good answer between many! Everybody takes as granted that a year has 365 days or just ignore the days... bad mistake... Another problem with other answers here (and elsewhere......) is that people go into complex computations without need. Lastly, no need for moment.js for just birthday, especially when computations may be done multiple times and consume CPU... THAT SAID, I would edit the answer and remove the new Date(assumed_string_date) and declare the date1, date2 as : Date – rubmz Feb 21 '23 at 06:05
2

Yep, moment.js is pretty good for this:

var moment = require('moment');
var startDate = new Date();
var endDate = new Date();
endDate.setDate(endDate.getFullYear() + 5); // Add 5 years to second date
console.log(moment.duration(endDate - startDate).years()); // This should returns 5
Michael Yurin
  • 1,021
  • 14
  • 18
1
function getYearDiff(startDate, endDate) {
    let yearDiff = endDate.getFullYear() - startDate.getFullYear();
    if (startDate.getMonth() > endDate.getMonth()) {
        yearDiff--;
    } else if (startDate.getMonth() === endDate.getMonth()) {
        if (startDate.getDate() > endDate.getDate()) {
            yearDiff--;
        } else if (startDate.getDate() === endDate.getDate()) {
            if (startDate.getHours() > endDate.getHours()) {
                yearDiff--;
            } else if (startDate.getHours() === endDate.getHours()) {
                if (startDate.getMinutes() > endDate.getMinutes()) {
                    yearDiff--;
                }
            }
        }
    }
    return yearDiff;
}

alert(getYearDiff(firstDate, secondDate));
user1942990
  • 60
  • 1
  • 6
1
getAge(month, day, year) {
    let yearNow = new Date().getFullYear();
    let monthNow = new Date().getMonth() + 1;
    let dayNow = new Date().getDate();
    if (monthNow === month && dayNow < day || monthNow < month) {
      return yearNow - year - 1;
    } else {
      return yearNow - year;
    }
  }
1

If you are using moment

/**
 * Convert date of birth into age
 * param {string} dateOfBirth - date of birth
 * param {string} dateToCalculate  -  date to compare
 * returns {number} - age
 */
function getAge(dateOfBirth, dateToCalculate) {
    const dob = moment(dateOfBirth);
    return moment(dateToCalculate).diff(dob, 'years');
};
Shyam Kumar
  • 586
  • 3
  • 17
1

If you want to calculate the years and keep the remainder of the time left for further calculations you can use this function most of the other answers discard the remaining time.

It returns the years and the remainder in milliseconds. This is useful if you want to calculate the time (days or minutes) left after you calculate the years.

The function works by first calculating the difference in years directly using *date.getFullYear()*. Then it checks if the last year between the two dates is up to a full year by setting the two dates to the same year. Eg:

oldDate= 1 July 2020, 
newDate= 1 June 2022, 
years =2020 -2022 =2

Now set old date to new date's year 2022

oldDate = 1 July, 2022

If the last year is not up to a full year then the year is subtracted by 1, the old date is set to the previous year and the interval from the previous year to the current date is calculated to give the remainder in milliseconds.

In the example since old date July 2022 is greater than June 2022 then it means a full year has not yet elapsed (from July 2021 to June 2022) therefore the year count is greater by 1. So years should be decreased by 1. And the actual year count from July 2020 to June 2022 is 1 year ,... months.

If the last year is a full year then the year count by *date.getFullYear()* is correct and the time that has elapsed from the current old date to new date is calculated as the remainder. If old date= 1 April, 2020, new date = 1 June, 2022 and old date is set to April 2022 after calculating the year =2. Eg: from April 2020 to June 2022 a duration of 2 years has passed with the remainder being the time from April 2022 to June 2022.

There are also checks for cases where the two dates are in the same year and if the user enters the dates in the wrong order the new Date is less recent than the old Date.

let getYearsAndRemainder = (newDate, oldDate) => {
    let remainder = 0;
    // get initial years between dates
    let years = newDate.getFullYear() - oldDate.getFullYear();
    if (years < 0) {// check to make sure the oldDate is the older of the two dates
        console.warn('new date is lesser than old date in year difference')
        years = 0;
    } else {
        // set the old date to the same year as new date
        oldDate.setFullYear(newDate.getFullYear());
            // check if the old date is less than new date in the same year
        if (oldDate - newDate > 0) {
            //if true, the old date is greater than the new date
            // the last but one year between the two dates is  not up to a year
            if (years != 0) {// dates given in inputs are in the same year, no need to calculate years if the number of years is 0
                console.log('Subtracting year');
                //set the old year to the previous year 
                years--;
                oldDate.setFullYear(oldDate.getFullYear() - 1);
            }
        }
    }
    //calculate the time difference between the old year and newDate.
    remainder = newDate - oldDate;
    if (remainder < 0) { //check for negative dates due to wrong inputs
        console.warn('old date is greater than new Date');
        console.log('new date', newDate, 'old date', oldDate);
    }

    return { years, remainder };
}

let old = new Date('2020-07-01');
console.log( getYearsAndRemainder(new Date(), old));
1
for(var y=birthyear; y <= thisyear; y++){ 

if( (y % 4 == 0 && y % 100 == 0) || y % 400 == 0 ) { 
 days = days-366;
 number_of_long_years++; 
} else {
    days=days-365;
}

year++;

}

can you try this way??

run
  • 1,170
  • 7
  • 14
0

Date calculation work via the Julian day number. You have to take the first of January of the two years. Then you convert the Gregorian dates into Julian day numbers and after that you take just the difference.

ceving
  • 21,900
  • 13
  • 104
  • 178
0

Maybe my function can explain better how to do this in a simple way without loop, calculations and/or libs

function checkYearsDifference(birthDayDate){
    var todayDate = new Date();
    var thisMonth = todayDate.getMonth();
    var thisYear = todayDate.getFullYear();
    var thisDay = todayDate.getDate();
    var monthBirthday = birthDayDate.getMonth(); 
    var yearBirthday = birthDayDate.getFullYear();
    var dayBirthday = birthDayDate.getDate();
    //first just make the difference between years
    var yearDifference = thisYear - yearBirthday;
    //then check months
    if (thisMonth == monthBirthday){
      //if months are the same then check days
      if (thisDay<dayBirthday){
        //if today day is before birthday day
        //then I have to remove 1 year
        //(no birthday yet)
        yearDifference = yearDifference -1;
      }
      //if not no action because year difference is ok
    }
    else {
      if (thisMonth < monthBirthday) {
        //if actual month is before birthday one
        //then I have to remove 1 year
        yearDifference = yearDifference -1;
      }
      //if not no action because year difference is ok
    }
    return yearDifference;
  }
0

if someone needs for interest calculation year in float format

function floatYearDiff(olddate, newdate) {
  var new_y = newdate.getFullYear();
  var old_y = olddate.getFullYear();
  var diff_y = new_y - old_y;
  var start_year = new Date(olddate);
  var end_year = new Date(olddate);
  start_year.setFullYear(new_y);
  end_year.setFullYear(new_y+1);
  if (start_year > newdate) {
    start_year.setFullYear(new_y-1);
    end_year.setFullYear(new_y);
    diff_y--;
  }
  var diff = diff_y + (newdate - start_year)/(end_year - start_year);
  return diff;
}
  • 1
    Please describe your answers in words too! – Alexis Jul 14 '19 at 19:52
  • Apart from not explaining anything, this is what I was looking for, where appropriately identifies exactly 1 year difference, but will also give you a decimal if not exactly a year – Todd Horst Aug 03 '23 at 18:29
0

Bro, moment.js is awesome for this: The diff method is what you want: http://momentjs.com/docs/#/displaying/difference/

The below function return array of years from the year to the current year.

const getYears = (from = 2017) => {
  const diff = moment(new Date()).diff(new Date(`01/01/${from}`), 'years') ;
  return [...Array(diff >= 0 ? diff + 1 : 0).keys()].map((num) => {
    return from + num;
  });
}

console.log(getYears(2016));
<script src="https://momentjs.com/downloads/moment.js"></script>
Murtaza Hussain
  • 3,851
  • 24
  • 30
0
function dateDiffYearsOnly( dateNew,dateOld) {
   function date2ymd(d){ w=new Date(d);return [w.getFullYear(),w.getMonth(),w.getDate()]}
   function ymd2N(y){return (((y[0]<<4)+y[1])<<5)+y[2]} // or 60 and 60 // or 13 and 32 // or 25 and 40 //// with ...
   function date2N(d){ return ymd2N(date2ymd(d))}

   return  (date2N(dateNew)-date2N(dateOld))>>9
}

test:

dateDiffYearsOnly(Date.now(),new Date(Date.now()-7*366*24*3600*1000));
dateDiffYearsOnly(Date.now(),new Date(Date.now()-7*365*24*3600*1000))
qulinxao
  • 183
  • 1
  • 10
0

I went for the following very simple solution. It does not assume you were born in 1970 and it also takes into account the hour of the given birthday date.

function age(birthday) {

    let now = new Date();
    let year = now.getFullYear();
    let years = year - birthday.getFullYear();
    birthday = new Date(birthday.getTime()); // clone
    birthday.setFullYear(year);
    return now >= birthday ? years : years - 1;
}
0

My approach: differenciates from the previous months and days, as for the very same day (sums up +1 year)

Here I'm using Quasar's Date Utils, but you can do the same with vanilla JS

The important part is making a diff between the months, and checking if birthMonth has passed from the curent one.

Same making a diff among days

   
        const today = new Date()
        const todaysMonth: number = today.getMonth() + 1
        const todaysDay: number = today.getDate()

        let birthDate = date.extractDate(member.birthDate, 'DD/MM/YYYY')
        const birthMonth: number = birthDate.getMonth() + 1
        const birthDay: number = birthDate.getDate()

        if (birthMonth > todaysMonth) {
          birthDate = date.addToDate(birthDate, { years: 1 })
        }

        if (birthMonth === todaysMonth && birthDay < todaysDay) {
          birthDate = date.addToDate(birthDate, { years: 1 })
        }
        return age = date.getDateDiff(today, birthDate, 'years')

Despertaweb
  • 1,672
  • 21
  • 29
0

Using date-fns (momentJS is now a legacy package):

Im assuming the formatting is 01/02/1900 = days/months/years

differenceInYears( new Date(),parse('01/02/1900','dd/MM/yyyy', new Date()) 
yoty66
  • 390
  • 2
  • 12
0

This is one of these things where you'd think you would come across a simple solution when you google it. But given how all of these answers are either a screen full of code or use deprecated libraries in addition to having problems like leap years or not following the convention that on your birthday you already are your increased age, I think that even well over a decade later writing a new answer is warranted.

function getUserAgeInFullYears(dateOfBirth: Date, comparisonDate = new Date()) {
  const yearsDifference = comparisonDate.getFullYear() - dateOfBirth.getFullYear();
  const monthsDifference = comparisonDate.getMonth() - dateOfBirth.getMonth();
  const daysDifference = comparisonDate.getDate() - dateOfBirth.getDate();

  const doNotSubtractOne = monthsDifference > 0 || (monthsDifference === 0 && daysDifference >= 0);
  return doNotSubtractOne ? yearsDifference : yearsDifference - 1;
}

For pure JS instead of TS, just remove : Date from dateOfBirth: Date.

At first, my code computes the difference between the comparison date (by default the current date) and the date of birth. This is always the user's date of birth or one more than that. It is one more than that if and only if the day and month of the user's birthday have not yet been reached in the year of the comparison date.

UTF-8
  • 575
  • 1
  • 5
  • 23
-1

This one Help you...

     $("[id$=btnSubmit]").click(function () {
        debugger
        var SDate = $("[id$=txtStartDate]").val().split('-');
        var Smonth = SDate[0];
        var Sday = SDate[1];
        var Syear = SDate[2];
        // alert(Syear); alert(Sday); alert(Smonth);
        var EDate = $("[id$=txtEndDate]").val().split('-');
        var Emonth = EDate[0];
        var Eday = EDate[1];
        var Eyear = EDate[2];
        var y = parseInt(Eyear) - parseInt(Syear);
        var m, d;
        if ((parseInt(Emonth) - parseInt(Smonth)) > 0) {
            m = parseInt(Emonth) - parseInt(Smonth);
        }
        else {
            m = parseInt(Emonth) + 12 - parseInt(Smonth);
            y = y - 1;
        }
        if ((parseInt(Eday) - parseInt(Sday)) > 0) {
            d = parseInt(Eday) - parseInt(Sday);
        }
        else {
            d = parseInt(Eday) + 30 - parseInt(Sday);
            m = m - 1;
        }
        // alert(y + " " + m + " " + d);
        $("[id$=lblAge]").text("your age is " + y + "years  " + m + "month  " + d + "days");
        return false;
    });