Moment.js months difference

moment#isbefore
moment diff months
moment difference between two dates
moment js difference between two dates in years, months, days
moment js cdn
moment js online
moment date difference in days
moment typescript

I've been using moment.js for a short while now, and it's made date manipulation a lot easier but I have a specific case that is failing, and I can't see why.

When calculating the diff between today (31st October 2013) and the 1st February 2014, the months diff comes back as 2, although there are 3 complete months and one day between the two dates.

Diff between 31st October and 31st January works fine: 3 months and zero days.

var mStartDate = moment([ periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate() ]);
var mTermDate = moment([ someDate.getFullYear(), someDate.getMonth(), someDate.getDate() ]);

console.log('periodStartDate: ' + periodStartDate);
console.log('someDate: ' + someDate);

// Years
var yearsDiff = mTermDate.diff(mStartDate, 'years');

// Months
var monthsDiff = mTermDate.diff(mStartDate, 'months', true);

The console logs the following:

periodStartDate: Thu Oct 31 2013 11:13:51 GMT+0000 (GMT)
someDate: Sat Feb 01 2014 11:13:51 GMT+0000 (GMT)
monthsDiff: 2

If I pass true as the boolean not to round, the months diff is

monthsDiff: 2.983050847457627 

Is this just a bug in Moment.js.diff()? Every single one of my other test cases pass successfully.

I think this has to do with the 'special handling' as described in The Fine Manual:

It is optimized to ensure that two months with the same date are always a whole number apart.

So Jan 15 to Feb 15 should be exactly 1 month.

Feb 28 to Mar 28 should be exactly 1 month.

Feb 28 2011 to Feb 28 2012 should be exactly 1 year.

Moment.js applies this special handling when dealing with 31 Jan and 31 Oct (having the same day):

// 31 Oct 2013 - 1 Feb 2014
> moment([2014, 1, 1]).diff(moment([2013, 9, 31]), 'months', true)
2.983050847457627

// 31 Oct 2013 - 31 Jan 2014
> moment([2014, 0, 31]).diff(moment([2013, 9, 31]), 'months', true)
3

// 31 Oct 2013 - 30 Jan 2014
> moment([2014, 0, 30]).diff(moment([2013, 9, 31]), 'months', true)
2.967741935483871

So the 2.98 value is correct, it's just that the second example turns the result into a 'calender months' difference.

(as for rounding down to 2, that's also documented on the same page)

Moment.js, You could get the difference in years and add that to the initial date; then get the difference in months and add that to the initial date again. In doing so, you can  Moment.js – Get difference between two dates in years, months and days. Updated on September 15, 2019 Kisan Patel You could get the difference in years and add that to the initial date; then get the difference in months and add that to the initial date again.

I went a different route trying to get the difference between two months

function getAbsoluteMonths(momentDate) {
  var months = Number(momentDate.format("MM"));
  var years = Number(momentDate.format("YYYY"));
  return months + (years * 12);
}

var startMonths = getAbsoluteMonths(start);
var endMonths = getAbsoluteMonths(end);

var monthDifference = endMonths - startMonths;

This made sense to me and since moment is doing some strange things with diff I just decided to make it clear what my result will be.

Diff month for months with a different number of days · Issue #3029 , Hello, I am trying to get diff in months between months with a different number of days. removed the lines of 'Moment.js' and started using just a bit 'Date.js' and normal JavaScript [bugfix] Fix #3029 Month difference #4666. moment ().diff (Moment|String|Number|Date|Array); moment ().diff (Moment|String|Number|Date|Array, String); moment ().diff (Moment|String|Number|Date|Array, String, Boolean); To get the difference in milliseconds, use moment#diff like you would use moment#from.

Simple And Easy Solution with correct value difference between two months if you are using moment Library

  const monthDifference =  moment(new Date(endDate)).diff(new Date(startDate), 'months', true);

If you want to add the number of days in endDate

 const monthDifference = moment(new Date(endDate.add(1, 'days'))).diff(new Date(startDate), 'months', true);

Docs, See the docs on moment#duration for more info. The supported measurements are years , months , weeks , days , hours , minutes , and seconds . For ease of  From the moment.js docs: format('E') stands for day of week. thus your diff is being computed on which day of the week, which has to be between 1 and 7. From the moment.js docs again, here is what they suggest:

Difference, xxxxxxxxxx. 8. 1. var today = moment('2014-05-31'),. 2. nextMonth = today.clone​();. 3. ​. 4. alert(nextMonth.toString());. 5. ​. 6. nextMonth.add('months', 1);. 7. ​. Not to mention that basically everything will be broken now -- a range slightly higher than a month will be considered as 2 months, and not just months, but everything. The only thing which might make sense it to set specific thresholds for rounding up (like if its above .95 round up), which will be approximate to 1 day.

moment js diff month comparisons - JSFiddle, The idea is to have 2 custom date fields and use moment.js to determine the difference between them in a format similar to 'x Years, x Months  Because different locales define week of year numbering differently, Moment.js added moment#week to get/set the localized week of the year. The week of the year varies depending on which day is the first day of the week (Sunday, Monday, etc), and which week is the first week of the year.

Use moment.js to calculate difference between 2 dates, This article introduces Moment.js, a JavaScript library for working with 7. console.log(`Difference is ${dateB.diff(dateC, 'months')} month(s)`);  When you call diff, moment.js calculates the difference in milliseconds. If the milliseconds is passed to duration , it is used to calculate duration which is correct. However. when you pass the same milliseconds to the moment() , it calculates the date that is milliseconds from(after) epoch/unix time that is January 1, 1970 (midnight UTC/GMT).

Comments
  • I've encountered this on version 2.2.1 - I can see it happening with 2.4.0 as well
  • Thanks Robert. But isn't it weird that the value goes up (when calculating difference with 31/01) compared to 30/01, then down again? I would expect something like 2.967, then 3, then 3.02 or something like that. If there are 3 complete months between two dates, how can there be less when I add one day? The other thing I do after all this, is that I display the difference in a "X months and Y days" manner. So... if there are 2 months, that takes me to the 31/12, and then there's 32 days to reach the 1st Feb.
  • @Khain because the days value is the same it clamps the value to a whole number (that's the "special handling"). For the other dates, it doesn't clamp and uses the exact (floating point) value.
  • @robertklep do you mean moment([2013, 10, 31]).diff ? May be a typo?
  • @LPG you mean to create an instance representing Oct 31st? That should be moment([2013, 9, 31]) (since months are 0-indexed, so 0 is January, 1 is February, etc).
  • from the latest moment library, just return d.month() + d.year()*12
  • Why multiply the years by 12? wouldn't this accomplish the same result without that?
  • I did 12 because if our start is 04-2017 and end is 01-2018 if you only took the months + the year would give you 2021 - 2019 = 4 which I'm looking for 9.