From: Tim Wood Date: Wed, 9 Jan 2013 18:38:15 +0000 (-0800) Subject: cleaning up year and month diffs X-Git-Tag: 2.0.0~17^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=644263afb23dda24d853cae12328cc7be90769d5;p=thirdparty%2Fmoment.git cleaning up year and month diffs --- diff --git a/moment.js b/moment.js index b45633ba8..d61f753d8 100644 --- a/moment.js +++ b/moment.js @@ -1091,17 +1091,18 @@ }, diff : function (input, val, asFloat) { - var inputMoment = this._isUTC ? moment(input).utc() : moment(input).local(), - zoneDiff = (this.zone() - inputMoment.zone()) * 6e4, - diff = this._d - inputMoment._d - zoneDiff, - year = this.year() - inputMoment.year(), - month = this.month() - inputMoment.month(), - date = this.date() - inputMoment.date(), + var that = this._isUTC ? moment(input).utc() : moment(input).local(), + zoneDiff = (this.zone() - that.zone()) * 6e4, + diff = (this - that) - zoneDiff, output; - if (val === 'months') { - output = year * 12 + month + date / 30; - } else if (val === 'years') { - output = year + (month + date / 30) / 12; + + if (val === 'years' || val === 'months') { + output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); + output += (this - moment(this).startOf('month')) / (864e5 * this.daysInMonth()); + output -= (that - moment(that).startOf('month')) / (864e5 * that.daysInMonth()); + if (val === 'years') { + output = output / 12; + } } else { output = val === 'seconds' ? diff / 1e3 : // 1000 val === 'minutes' ? diff / 6e4 : // 1000 * 60 @@ -1211,7 +1212,7 @@ }, dayOfYear : function (input) { - var dayOfYear = moment(this).startOf('day').diff(moment(this).startOf('year'), 'days') + 1; + var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; return input == null ? dayOfYear : this.add("d", (input - dayOfYear)); }, diff --git a/test/moment/diff.js b/test/moment/diff.js index b1fc352fa..f2f55037d 100644 --- a/test/moment/diff.js +++ b/test/moment/diff.js @@ -1,5 +1,9 @@ var moment = require("../../moment"); +function equal(test, a, b, message) { + test.ok(Math.abs(a - b) < 0.000001, message); +} + exports.diff = { "diff" : function(test) { test.expect(5); @@ -16,10 +20,9 @@ exports.diff = { }, "diff key after" : function(test) { - test.expect(9); + test.expect(8); test.equal(moment([2010]).diff([2011], 'years'), -1, "year diff"); - test.equal(moment([2010]).diff([2011, 6], 'years', true), -1.5, "year diff, float"); test.equal(moment([2010]).diff([2010, 2], 'months'), -2, "month diff"); test.equal(moment([2010]).diff([2010, 0, 7], 'weeks'), -1, "week diff"); test.equal(moment([2010]).diff([2010, 0, 21], 'weeks'), -3, "week diff"); @@ -31,10 +34,9 @@ exports.diff = { }, "diff key before" : function(test) { - test.expect(9); + test.expect(8); test.equal(moment([2011]).diff([2010], 'years'), 1, "year diff"); - test.equal(moment([2011, 6]).diff([2010], 'years', true), 1.5, "year diff, float"); test.equal(moment([2010, 2]).diff([2010], 'months'), 2, "month diff"); test.equal(moment([2010, 0, 4]).diff([2010], 'days'), 3, "day diff"); test.equal(moment([2010, 0, 7]).diff([2010], 'weeks'), 1, "week diff"); @@ -89,6 +91,46 @@ exports.diff = { test.ok(moment([2012, 1, 19]).diff(moment([2002, 1, 20]), 'years', true) < 10, "year diff should include date of month"); + test.done(); + }, + + "year diffs" : function (test) { + test.expect(8); + + var elevenMonthsThirtyDays = (11 + 30/31) / 12, + thirtyDays = (30/31) / 12, + elevenMonthsThirtyHalfDays = (11 + 30.5/31) / 12, + thirtyHalfDays = (30.5/31) / 12; + + equal(test, moment([2012, 0, 1]).diff([2012, 11, 31], 'years', true), -elevenMonthsThirtyDays, 'start to end of a leap year'); + equal(test, moment([2012, 0, 1]).diff([2012, 0, 31], 'years', true), -thirtyDays, '30 days in a leap year'); + equal(test, moment([2011, 0, 1]).diff([2011, 11, 31], 'years', true), -elevenMonthsThirtyDays, 'start to end of a non-leap year'); + equal(test, moment([2011, 0, 1]).diff([2011, 0, 31], 'years', true), -thirtyDays, '30 days in a non-leap year'); + equal(test, moment([2011, 0, 1]).diff([2011, 11, 31, 12], 'years', true), -elevenMonthsThirtyHalfDays, 'start to end of a non-leap year'); + equal(test, moment([2011, 0, 1]).diff([2011, 0, 31, 12], 'years', true), -thirtyHalfDays, '30.5 days in a non-leap year'); + equal(test, moment([2011, 0, 1]).diff([2012, 11, 31, 12], 'years', true), -(1 + elevenMonthsThirtyHalfDays), 'spanning two years'); + equal(test, moment([2011, 0, 1]).diff([2012, 0, 31, 12], 'years', true), -(1 + thirtyHalfDays), '1 year 30.5 days spanning two years'); + + test.done(); + }, + + "year diff over new year" : function (test) { + test.expect(2); + + equal(test, moment([2011, 11, 31]).diff([2012, 11, 31], 'years', true), -1, '1 year difference over the new year should correct'); + equal(test, moment([2011, 11, 31]).diff([2012, 0, 1], 'years', true), -(1/31) / 12, '1 day difference over the new year should correct'); + + test.done(); + }, + + "month diffs" : function (test) { + test.expect(4); + + equal(test, moment([2012, 0, 1]).diff([2012, 11, 31], 'months', true), -(11 + 30 / 31), '11 month 30 day diff should be 11+30/31 months'); + equal(test, moment([2012, 0, 1]).diff([2012, 0, 31], 'months', true), -30 / 31, '30 day diff should be 30/31 months'); + equal(test, moment([2012, 0, 1]).diff([2012, 11, 31, 12], 'months', true), -(11 + 30.5 / 31), '11 month 30.5 day diff should be 11+30.5/31 months'); + equal(test, moment([2012, 0, 1]).diff([2012, 0, 31, 12], 'months', true), -30.5 / 31, '30.5 day diff should be 30.5/31 months'); + test.done(); } };