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.
Advertisement
Answer
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)