Month difference between two dates in JavaScript

How would I determine the difference for two Date () objects in JavaScript, and only return the number of months in the difference?

Any help would be great :)

+112
javascript date datediff
Mar 29 '10 at 7:34
source share
24 answers

The definition of "number of months in difference" is subject to many interpretations. :-)

You can get the year, month, and day of the month from a JavaScript date object. Depending on what information you are looking for, you can use them to determine the number of months between two points in time.

For example, outside the cuff, this finds out how many full months lie between two dates, not counting partial months (for example, except for the month in which each date is located):

function monthDiff(d1, d2) { var months; months = (d2.getFullYear() - d1.getFullYear()) * 12; months -= d1.getMonth() + 1; months += d2.getMonth(); return months <= 0 ? 0 : months; } monthDiff( new Date(2008, 10, 4), // November 4th, 2008 new Date(2010, 2, 12) // March 12th, 2010 ); // Result: 15: December 2008, all of 2009, and Jan & Feb 2010 monthDiff( new Date(2010, 0, 1), // January 1st, 2010 new Date(2010, 2, 12) // March 12th, 2010 ); // Result: 1: February 2010 is the only full month between them monthDiff( new Date(2010, 1, 1), // February 1st, 2010 new Date(2010, 2, 12) // March 12th, 2010 ); // Result: 0: There are no *full* months between them 

(Note that the month values ​​in JavaScript start with 0 = January.)

Including fractional months in the foregoing is much more difficult, because three days in a typical February make up the greater part of this month (~ 10.714%) than three days in August (~ 9.677%), and, of course, even February a moving target, depending on is he a leap year.

There are also some date and time libraries for JavaScript that probably simplify this task.

+199
Mar 29 '10 at 7:49
source share

If you do not count the day of the month, this is a much simpler solution.

 function monthDiff(dateFrom, dateTo) { return dateTo.getMonth() - dateFrom.getMonth() + (12 * (dateTo.getFullYear() - dateFrom.getFullYear())) } //examples console.log(monthDiff(new Date(2000, 01), new Date(2000, 02))) // 1 console.log(monthDiff(new Date(1999, 02), new Date(2000, 02))) // 12 full year console.log(monthDiff(new Date(2009, 11), new Date(2010, 0))) // 1 
+60
Nov 30 '10 at 10:59
source share

Sometimes you can only get the number of months between two dates that completely ignore the daily part. For example, if you had two dates - 2013/06/21 and 2013/10 / 18-, and you only cared about parts 2013/06 and 2013/10, here are the scenarios and possible solutions:

 var date1=new Date(2013,5,21);//Remember, months are 0 based in JS var date2=new Date(2013,9,18); var year1=date1.getFullYear(); var year2=date2.getFullYear(); var month1=date1.getMonth(); var month2=date2.getMonth(); if(month1===0){ //Have to take into account month1++; month2++; } var numberOfMonths; 

1.If you want just the number of months between two dates, excluding both month1 and month2

 numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1; 

2. If you want to include any of the months

 numberOfMonths = (year2 - year1) * 12 + (month2 - month1); 

3. If you want to include both months

 numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1; 
+28
Mar 01 '13 at 13:25
source share

If you need to count full months, regardless of whether the month is 28, 29, 30 or 31 days. Below should work.

 var months = to.getMonth() - from.getMonth() + (12 * (to.getFullYear() - from.getFullYear())); if(to.getDate() < from.getDate()){ months--; } return months; 

This is an extended version of the answer https://stackoverflow.com/a/167958/2127 , but corrects the case where it calculates 1 month for the case from January 31 to February 1 (1 day).

This will cover the following:

  • January 1 - January 31 ---> 30days ---> will lead to 0 (logical, since this is not a full month)
  • February 1 - March 1 ---> 28 or 29 days ---> will result in 1 (logical, since this is a full month).
  • February 15 - March 15 ---> 28 or 29 days ---> will result in 1 (logical from a month has passed)
  • January 31 - February 1 ---> 1 day ---> will lead to 0 (obviously, but the mentioned answer in the results of the message for 1 month)
+22
Jan 09 '14 at 13:02
source share

Here's a function that accurately provides the number of months between two dates.
The default behavior is only for whole months, for example. 3 months and 1 day will result in a difference of 3 months. You can prevent this by setting the roundUpFractionalMonths parameter to true , so the difference of 3 months and 1 day will be returned after 4 months.

The accepted answer above (TJ Crowder's answer) is inaccurate, sometimes it returns incorrect values.

For example, monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015')) returns 0 , which is obviously incorrect. The correct difference is either 1 month or 2 months of rounding.

Here is the function I wrote:

 function getMonthsBetween(date1,date2,roundUpFractionalMonths) { //Months will be calculated between start and end dates. //Make sure start date is less than end date. //But remember if the difference should be negative. var startDate=date1; var endDate=date2; var inverse=false; if(date1>date2) { startDate=date2; endDate=date1; inverse=true; } //Calculate the differences between the start and end dates var yearsDifference=endDate.getFullYear()-startDate.getFullYear(); var monthsDifference=endDate.getMonth()-startDate.getMonth(); var daysDifference=endDate.getDate()-startDate.getDate(); var monthCorrection=0; //If roundUpFractionalMonths is true, check if an extra month needs to be added from rounding up. //The difference is done by ceiling (round up), eg 3 months and 1 day will be 4 months. if(roundUpFractionalMonths===true && daysDifference>0) { monthCorrection=1; } //If the day difference between the 2 months is negative, the last month is not a whole month. else if(roundUpFractionalMonths!==true && daysDifference<0) { monthCorrection=-1; } return (inverse?-1:1)*(yearsDifference*12+monthsDifference+monthCorrection); }; 
+21
Nov 14 '14 at 13:22
source share

Month difference between two dates in JavaScript:

  start_date = new Date(year, month, day); //Create start date object by passing appropiate argument end_date = new Date(new Date(year, month, day) 

Total months between start_date and end_date:

  total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth()) 
+7
Mar 15 '14 at 13:41
source share

I know it's really late, but post it anyway, just in case it helps others. Here is a function I came across that seems to be well versed in the differences between months between two dates. This is admittedly much more useless than Mr. Cowder's, but gives more accurate results by going through the date object. This is in AS3, but you just have to remove strong typing and you will have JS. Feel free to look your best!

  function countMonths ( startDate:Date, endDate:Date ):int { var stepDate:Date = new Date; stepDate.time = startDate.time; var monthCount:int; while( stepDate.time <= endDate.time ) { stepDate.month += 1; monthCount += 1; } if ( stepDate != endDate ) { monthCount -= 1; } return monthCount; } 
+6
Jul 21 '10 at 21:28
source share

Consider each date in months, then subtract to find the difference.

 var past_date = new Date('11/1/2014'); var current_date = new Date(); var difference = (current_date.getFullYear()*12 + current_date.getMonth()) - (past_date.getFullYear()*12 + past_date.getMonth()); 

This will give you the difference between the months between the two dates, ignoring the days.

+5
Nov 22 '15 at 6:17
source share

Expand on @TJ answer, if you are looking for simple months and not full calendar months, you can just check if d2 is greater than a date or value than d1. That is, if d2 is later in the month than d1 in the month, then another month. Therefore, you should simply do this:

 function monthDiff(d1, d2) { var months; months = (d2.getFullYear() - d1.getFullYear()) * 12; months -= d1.getMonth() + 1; months += d2.getMonth(); // edit: increment months if d2 comes later in its month than d1 in its month if (d2.getDate() >= d1.getDate()) months++ // end edit return months <= 0 ? 0 : months; } monthDiff( new Date(2008, 10, 4), // November 4th, 2008 new Date(2010, 2, 12) // March 12th, 2010 ); // Result: 16; 4 Nov – 4 Dec '08, 4 Dec '08 – 4 Dec '09, 4 Dec '09 – 4 March '10 

This does not fully take into account time problems (for example, March 3 at 16:00 and April 3 at 15:00), but it is more accurate and just a couple of lines of code.

+4
Mar 18 '14 at 21:33
source share

There are two approaches, mathematical and fast, but prone to whims in the calendar, or iterative and slow, but handling all oddities (or at least the delegates processing them in a well-tested library).

If you iterate through the calendar by increasing the start date by one month and see if the end date is passed. This delegates the handling of anomalies to the built-in Date () classes, but can be slow if you do this for a lot of dates. James's answer takes this approach. As much as I don't like this idea, I think this is the β€œsafest” approach, and if you do only one calculation, the performance difference is really negligible. We tend to try to redefine tasks that will be performed only once.

Now, if , you are calculating this function in a data set, you probably do not want to run this function on each line (or, God forbid, several times per record). In this case, you can use almost any of the other answers here, except for the accepted answer, which is simply incorrect (the difference between new Date() and new Date() is -1)?

Here is my hit on a mathematical and quick approach that takes into account different monthly lengths and leap years. You really should use only such a function if you will apply it to a data set (repeat this calculation again and again). If you just need to do this once, use the iterative approach of James above since you are delegating the handling of all (many) exceptions for the Date () object.

 function diffInMonths(from, to){ var months = to.getMonth() - from.getMonth() + (12 * (to.getFullYear() - from.getFullYear())); if(to.getDate() < from.getDate()){ var newFrom = new Date(to.getFullYear(),to.getMonth(),from.getDate()); if (to < newFrom && to.getMonth() == newFrom.getMonth() && to.getYear() %4 != 0){ months--; } } return months; } 
+4
Feb 27 '15 at 18:54
source share

Here you go the other way with a smaller loop:

 calculateTotalMonthsDifference = function(firstDate, secondDate) { var fm = firstDate.getMonth(); var fy = firstDate.getFullYear(); var sm = secondDate.getMonth(); var sy = secondDate.getFullYear(); var months = Math.abs(((fy - sy) * 12) + fm - sm); var firstBefore = firstDate > secondDate; firstDate.setFullYear(sy); firstDate.setMonth(sm); firstBefore ? firstDate < secondDate ? months-- : "" : secondDate < firstDate ? months-- : ""; return months; } 
+3
Dec 07 '11 at 13:30
source share

This should work fine:

 function monthDiff(d1, d2) { var months; months = (d2.getFullYear() - d1.getFullYear()) * 12; months += d2.getMonth() - d1.getMonth(); return months; } 
+2
May 6 '16 at 10:06 PM
source share
 function calcualteMonthYr(){ var fromDate =new Date($('#txtDurationFrom2').val()); //date picker (text fields) var toDate = new Date($('#txtDurationTo2').val()); var months=0; months = (toDate.getFullYear() - fromDate.getFullYear()) * 12; months -= fromDate.getMonth(); months += toDate.getMonth(); if (toDate.getDate() < fromDate.getDate()){ months--; } $('#txtTimePeriod2').val(months); } 
+1
Sep 29 '15 at 6:07
source share

Calculate the difference between the two dates, including the fraction of the month (days).




 var difference = (date2.getDate() - date1.getDate()) / 30 + date2.getMonth() - date1.getMonth() + (12 * (date2.getFullYear() - date1.getFullYear())); 

For example:
date1 : 09/24/2015 (September 24, 2015)
date2 : 11/11/2015 (November 9, 2015)
difference: 2.5 (months)

+1
Nov 03 '15 at 16:44
source share

The following code returns full months between two dates, also taking into account the number of days of incomplete months.

 var monthDiff = function(d1, d2) { if( d2 < d1 ) { var dTmp = d2; d2 = d1; d1 = dTmp; } var months = (d2.getFullYear() - d1.getFullYear()) * 12; months -= d1.getMonth() + 1; months += d2.getMonth(); if( d1.getDate() <= d2.getDate() ) months += 1; return months; } monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 20)) > 1 monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 19)) > 0 monthDiff(new Date(2015, 01, 20), new Date(2015, 01, 22)) > 0 
+1
Apr 25 '16 at 22:07
source share
 function monthDiff(d1, d2) { var months, d1day, d2day, d1new, d2new, diffdate,d2month,d2year,d1maxday,d2maxday; months = (d2.getFullYear() - d1.getFullYear()) * 12; months -= d1.getMonth() + 1; months += d2.getMonth(); months = (months <= 0 ? 0 : months); d1day = d1.getDate(); d2day = d2.getDate(); if(d1day > d2day) { d2month = d2.getMonth(); d2year = d2.getFullYear(); d1new = new Date(d2year, d2month-1, d1day,0,0,0,0); var timeDiff = Math.abs(d2.getTime() - d1new.getTime()); diffdate = Math.abs(Math.ceil(timeDiff / (1000 * 3600 * 24))); d1new = new Date(d2year, d2month, 1,0,0,0,0); d1new.setDate(d1new.getDate()-1); d1maxday = d1new.getDate(); months += diffdate / d1maxday; } else { if(!(d1.getMonth() == d2.getMonth() && d1.getFullYear() == d2.getFullYear())) { months += 1; } diffdate = d2day - d1day + 1; d2month = d2.getMonth(); d2year = d2.getFullYear(); d2new = new Date(d2year, d2month + 1, 1, 0, 0, 0, 0); d2new.setDate(d2new.getDate()-1); d2maxday = d2new.getDate(); months += diffdate / d2maxday; } return months; 

}

+1
Oct 16 '16 at 13:17
source share

below logic will extract the difference in months

 (endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth()) 
+1
Aug 16 '17 at 0:01
source share
 function monthDiff(date1, date2, countDays) { countDays = (typeof countDays !== 'undefined') ? countDays : false; if (!date1 || !date2) { return 0; } let bigDate = date1; let smallDate = date2; if (date1 < date2) { bigDate = date2; smallDate = date1; } let monthsCount = (bigDate.getFullYear() - smallDate.getFullYear()) * 12 + (bigDate.getMonth() - smallDate.getMonth()); if (countDays && bigDate.getDate() < smallDate.getDate()) { --monthsCount; } return monthsCount; } 
+1
Nov 21 '18 at 18:30
source share

anyVar = (((DisplayTo.getFullYear () * 12) + DisplayTo.getMonth ()) - ((DisplayFrom.getFullYear () * 12) + DisplayFrom.getMonth ()));

0
Feb 11 '16 at 6:03
source share

See what I use:

 function monthDiff() { var startdate = Date.parseExact($("#startingDate").val(), "dd/MM/yyyy"); var enddate = Date.parseExact($("#endingDate").val(), "dd/MM/yyyy"); var months = 0; while (startdate < enddate) { if (startdate.getMonth() === 1 && startdate.getDate() === 28) { months++; startdate.addMonths(1); startdate.addDays(2); } else { months++; startdate.addMonths(1); } } return months; } 
0
Aug 07 '17 at 12:31 on
source share

It also takes days into account and converts them over several months.

 function monthDiff(d1, d2) { var months; months = (d2.getFullYear() - d1.getFullYear()) * 12; //calculates months between two years months -= d1.getMonth() + 1; months += d2.getMonth(); //calculates number of complete months between two months day1 = 30-d1.getDate(); day2 = day1 + d2.getDate(); months += parseInt(day2/30); //calculates no of complete months lie between two dates return months <= 0 ? 0 : months; } monthDiff( new Date(2017, 8, 8), // Aug 8th, 2017 (d1) new Date(2017, 12, 12) // Dec 12th, 2017 (d2) ); //return value will be 4 months 
0
Dec 08 '17 at 12:21
source share

For prosperity

With Moment.js, you can achieve this by doing:

 const monthsLeft = moment(endDate).diff(moment(startDate), 'month'); 
0
Feb 07 '19 at 22:05
source share

You can also consider this solution, this function returns the monthly difference in integers or numbers.

Passing the start date as the first or last param is fault tolerant. This means that the function will still return the same value.

 const diffInMonths = (end, start) => { var timeDiff = Math.abs(end.getTime() - start.getTime()); return Math.round(timeDiff / (2e3 * 3600 * 365)); } const result = diffInMonths(new Date(2015, 3, 28), new Date(2010, 1, 25)); // shows month difference as integer/number console.log(result); 
0
Feb 15 '19 at 9:48
source share

One approach is to write a simple Java web service (REST / JSON) that uses the JODA library

http://joda-time.sourceforge.net/faq.html#datediff

to calculate the difference between two dates and call this service from javascript.

This assumes your back end is in Java.

-6
Feb 19 '12 at 2:00
source share



All Articles