]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
fixing month and year diffs to match expectations 571/head
authorTim Wood <washwithcare@gmail.com>
Wed, 16 Jan 2013 18:28:23 +0000 (10:28 -0800)
committerTim Wood <washwithcare@gmail.com>
Wed, 16 Jan 2013 18:28:23 +0000 (10:28 -0800)
moment.js
test/moment/diff.js

index d61f753d87499a0e3c0e3bcfb583f99803de7377..c5f5eb069e520f6ce19ebd848ae89676234859d5 100644 (file)
--- a/moment.js
+++ b/moment.js
             return this;
         },
 
-        diff : function (input, val, asFloat) {
+        diff : function (input, units, asFloat) {
             var that = this._isUTC ? moment(input).utc() : moment(input).local(),
                 zoneDiff = (this.zone() - that.zone()) * 6e4,
-                diff = (this - that) - zoneDiff,
-                output;
+                diff, output;
 
-            if (val === 'years' || val === 'months') {
+            if (units) {
+                units = units.replace(/s$/, '');
+            }
+
+            if (units === 'year' || units === 'month') {
+                diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
                 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 += ((this - moment(this).startOf('month')) - (that - moment(that).startOf('month'))) / diff;
+                if (units === 'year') {
                     output = output / 12;
                 }
             } else {
-                output = val === 'seconds' ? diff / 1e3 : // 1000
-                    val === 'minutes' ? diff / 6e4 : // 1000 * 60
-                    val === 'hours' ? diff / 36e5 : // 1000 * 60 * 60
-                    val === 'days' ? diff / 864e5 : // 1000 * 60 * 60 * 24
-                    val === 'weeks' ? diff / 6048e5 : // 1000 * 60 * 60 * 24 * 7
+                diff = (this - that) - zoneDiff;
+                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
                     diff;
             }
             return asFloat ? output : round(output);
index f2f55037d8cf66836126f6bfc08b6ecd780f7796..bd5ffbce41877f99f8d553dc9d138ba24292d1cb 100644 (file)
@@ -1,7 +1,7 @@
 var moment = require("../../moment");
 
 function equal(test, a, b, message) {
-    test.ok(Math.abs(a - b) < 0.000001, message);
+    test.ok(Math.abs(a - b) < 0.00000001, "(" + a + " === " + b + ") " + message);
 }
 
 exports.diff = {
@@ -94,42 +94,36 @@ exports.diff = {
         test.done();
     },
 
-    "year diffs" : function (test) {
+    "month 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');
+        // due to floating point math errors, these tests just need to be accurate within 0.00000001
+        equal(test, moment([2012, 0, 1]).diff([2012, 1, 1], 'months', true), -1, 'Jan 1 to Feb 1 should be 1 month');
+        equal(test, moment([2012, 0, 1]).diff([2012, 0, 1, 12], 'months', true), -0.5/31, 'Jan 1 to Jan 1 noon should be 0.5/31 months');
+        equal(test, moment([2012, 0, 15]).diff([2012, 1, 15], 'months', true), -1, 'Jan 15 to Feb 15 should be 1 month');
+        equal(test, moment([2012, 0, 28]).diff([2012, 1, 28], 'months', true), -1, 'Jan 28 to Feb 28 should be 1 month');
+        equal(test, moment([2012, 0, 31]).diff([2012, 1, 29], 'months', true), -1 + (2/30), 'Jan 31 to Feb 29 should be 1 - (2/30) months');
+        equal(test, moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), -2 + (30/31), 'Jan 31 to Mar 1 should be 2 - (30/31) months');
+        equal(test, moment([2012, 0, 31]).diff([2012, 2, 1, 12], 'months', true), -2 + (29.5/31), 'Jan 31 to Mar 1 should be 2 - (29.5/31) months');
+        equal(test, moment([2012, 0, 1]).diff([2012, 0, 31], 'months', true), -(30 / 31), 'Jan 1 to Jan 31 should be 30/31 months');
 
         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');
+    "year diffs" : function (test) {
+        test.expect(10);
+
+        // due to floating point math errors, these tests just need to be accurate within 0.00000001
+        equal(test, moment([2012, 0, 1]).diff([2013, 0, 1], 'years', true), -1, 'Jan 1 2012 to Jan 1 2013 should be 1 year');
+        equal(test, moment([2012, 1, 28]).diff([2013, 1, 28], 'years', true), -1, 'Feb 28 2012 to Feb 28 2013 should be 1 year');
+        equal(test, moment([2012, 2, 1]).diff([2013, 2, 1], 'years', true), -1, 'Mar 1 2012 to Mar 1 2013 should be 1 year');
+        equal(test, moment([2012, 11, 1]).diff([2013, 11, 1], 'years', true), -1, 'Dec 1 2012 to Dec 1 2013 should be 1 year');
+        equal(test, moment([2012, 11, 31]).diff([2013, 11, 31], 'years', true), -1, 'Dec 31 2012 to Dec 31 2013 should be 1 year');
+        equal(test, moment([2012, 0, 1]).diff([2013, 6, 1], 'years', true), -1.5, 'Jan 1 2012 to Jul 1 2013 should be 1.5 years');
+        equal(test, moment([2012, 0, 31]).diff([2013, 6, 31], 'years', true), -1.5, 'Jan 31 2012 to Jul 31 2013 should be 1.5 years');
+        equal(test, moment([2012, 0, 1]).diff([2013, 0, 1, 12], 'years', true), -1-(0.5/31)/12, 'Jan 1 2012 to Jan 1 2013 noon should be 1+(0.5/31)/12 years');
+        equal(test, moment([2012, 0, 1]).diff([2013, 6, 1, 12], 'years', true), -1.5-(0.5/31)/12, 'Jan 1 2012 to Jul 1 2013 noon should be 1.5+(0.5/31)/12 years');
+        equal(test, moment([2012, 1, 29]).diff([2013, 1, 28], 'years', true), -1 + (1/28.5)/12, 'Feb 29 2012 to Feb 28 2013 should be 1-(1/28.5)/12 years');
 
         test.done();
     }