Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moment.js months difference

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.

like image 323
Khain Avatar asked Oct 31 '13 11:10

Khain


People also ask

How do you find the moment difference in dates?

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 . To get the difference in another unit of measurement, pass that measurement as the second argument.

How do you find the month from a moment?

The moment(). daysInMonth() function is used to get the number of days in month of a particular month in Node.

What is moment diff?

The moment(). diff() function is used to get the difference in milliseconds of given dates which are passed as parameter to this function. Syntax: moment(). diff(Moment|String|Number|Date|Array, String, Boolean);

Is after Momentjs?

js isAfter() Function. You can check whether a date is after a particular date in Moment. js using the isAfter() function that checks if a moment is after another moment. The first argument will be parsed as a moment, if not already so.


3 Answers

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)

like image 192
robertklep Avatar answered Sep 30 '22 21:09

robertklep


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.

like image 20
MrB Avatar answered Sep 30 '22 23:09

MrB


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);
like image 29
Gaurav verma Avatar answered Sep 30 '22 22:09

Gaurav verma