units = normalizeUnits(units);
if (units === 'year' || units === 'month') {
+ // average number of days in the months in the given dates
diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
+ // difference in months
output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
- output += ((this - moment(this).startOf('month')) - (that - moment(that).startOf('month'))) / diff;
+ // adjust by taking difference in days, average number of days
+ // and dst in the given months.
+ output += ((this - moment(this).startOf('month')) -
+ (that - moment(that).startOf('month'))) / diff;
+ // same as above but with zones, to negate all dst
+ output -= ((this.zone() - moment(this).startOf('month').zone()) -
+ (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff;
if (units === 'year') {
output = output / 12;
}
} else {
- diff = (this - that) - zoneDiff;
+ diff = (this - that);
output = units === 'second' ? diff / 1e3 : // 1000
units === 'minute' ? diff / 6e4 : // 1000 * 60
units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
- units === 'day' ? diff / 864e5 : // 1000 * 60 * 60 * 24
- units === 'week' ? diff / 6048e5 : // 1000 * 60 * 60 * 24 * 7
+ units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
+ units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
diff;
}
return asFloat ? output : absRound(output);
},
"diff across DST" : function(test) {
- test.expect(2);
+ test.expect(9);
test.equal(moment([2012, 2, 24]).diff([2012, 2, 10], 'weeks', true), 2, "diff weeks across DST");
- test.equal(moment([2012, 2, 24]).diff([2012, 2, 10], 'days', true), 14, "diff weeks across DST");
+ test.equal(moment([2012, 2, 24]).diff([2012, 2, 10], 'days', true), 14, "diff days across DST");
+ test.equal(moment([2012, 2, 11]).diff([2012, 2, 11, 12], 'hours', true), -11, "diff hours across DST");
+ test.equal(moment([2012, 2, 11]).diff([2012, 2, 11, 12], 'days', true), -0.5, "diff days across DST");
+ test.equal(moment([2012, 2, 11]).diff([2012, 2, 11, 12], 'months', true), -1/62, "diff months across DST (half day in 31 day month)");
+ test.equal(moment([2012, 2, 11]).diff([2012, 2, 11, 12], 'months', true), -1/62, "diff months across DST (half day in 31 day month)");
+ test.equal(moment([2013, 10, 2]).diff([2013, 10, 17], 'months', true), -0.5, 'diff months across DST (15 days in 30 day month)')
+ test.equal(moment([2013, 10, 2]).diff([2013, 10, 17], 'days', true), -15, 'diff days across DST')
+ test.equal(moment([2013, 10, 2]).diff([2013, 10, 17], 'hours', true), -15 * 24 - 1, 'diff hours across DST (15 days minus 1 hour DST)')
test.done();
},