]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
Implement accurate moment.duration({from, to})
authorIskren Chernev <iskren.chernev@gmail.com>
Sat, 26 Apr 2014 08:28:15 +0000 (01:28 -0700)
committerIskren Chernev <iskren.chernev@gmail.com>
Thu, 19 Jun 2014 04:56:11 +0000 (21:56 -0700)
moment.js
test/moment/duration_from_moments.js [new file with mode: 0644]

index 83282c6fdbab67e9362c6e7f0421333f5a000090..f2604d825d532f0665fc1bfc518842b0638b8ffc 100644 (file)
--- a/moment.js
+++ b/moment.js
         return (sign ? (forceSign ? '+' : '') : '-') + output;
     }
 
+    function positiveMomentsDifference(base, other) {
+        var res = {milliseconds: 0, months: 0};
+
+        res.months = other.month() - base.month() +
+            (other.year() - base.year()) * 12;
+        if (base.clone().add(res.months, 'M').isAfter(other)) {
+            -- res.months;
+        }
+
+        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
+
+        return res;
+    }
+
+    function momentsDifference(base, other) {
+        var res;
+        other = makeAs(other, base);
+        if (base.isBefore(other)) {
+            res = positiveMomentsDifference(base, other);
+        } else {
+            res = positiveMomentsDifference(other, base);
+            res.milliseconds = - res.milliseconds;
+            res.months = - res.months;
+        }
+
+        return res;
+    }
+
     // helper function for _.addTime and _.subtractTime
     function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
         var milliseconds = duration._milliseconds,
             match = null,
             sign,
             ret,
-            parseIso;
+            parseIso,
+            diffRes;
 
         if (moment.isDuration(input)) {
             duration = {
                 s: parseIso(match[7]),
                 w: parseIso(match[8])
             };
+        } else if (typeof duration === "object" &&
+                ("from" in duration || "to" in duration)) {
+            diffRes = momentsDifference(moment(duration.from), moment(duration.to));
+
+            duration = {};
+            duration.ms = diffRes.milliseconds;
+            duration.M = diffRes.months;
         }
 
         ret = new Duration(duration);
diff --git a/test/moment/duration_from_moments.js b/test/moment/duration_from_moments.js
new file mode 100644 (file)
index 0000000..71d0f98
--- /dev/null
@@ -0,0 +1,56 @@
+var moment = require("../../moment");
+
+exports.duration_from_moments = {
+    setUp: function (done) {
+        moment.createFromInputFallback = function () {
+            throw new Error("input not handled by moment");
+        };
+        done();
+    },
+
+    "pure year diff" : function (test) {
+        var m1 = moment("2012-01-01T00:00:00.000Z"),
+            m2 = moment("2013-01-01T00:00:00.000Z");
+
+        test.equal(moment.duration({from: m1, to: m2}).as("years"), 1, "year moment difference");
+        test.equal(moment.duration({from: m2, to: m1}).as("years"), -1, "negative year moment difference");
+        test.done();
+    },
+
+    "month and day diff" : function (test) {
+        var m1 = moment("2012-01-15T00:00:00.000Z"),
+            m2 = moment("2012-02-17T00:00:00.000Z"),
+            d = moment.duration({from: m1, to: m2});
+
+        test.equal(d.get("days"), 2);
+        test.equal(d.get("months"), 1);
+        test.done();
+    },
+
+    "day diff, separate months" : function (test) {
+        var m1 = moment("2012-01-15T00:00:00.000Z"),
+            m2 = moment("2012-02-13T00:00:00.000Z"),
+            d = moment.duration({from: m1, to: m2});
+
+        test.equal(d.as("days"), 29);
+        test.done();
+    },
+
+    "hour diff" : function (test) {
+        var m1 = moment("2012-01-15T17:00:00.000Z"),
+            m2 = moment("2012-01-16T03:00:00.000Z"),
+            d = moment.duration({from: m1, to: m2});
+
+        test.equal(d.as("hours"), 10);
+        test.done();
+    },
+
+    "minute diff" : function (test) {
+        var m1 = moment("2012-01-15T17:45:00.000Z"),
+            m2 = moment("2012-01-16T03:15:00.000Z"),
+            d = moment.duration({from: m1, to: m2});
+
+        test.equal(d.as("hours"), 9.5);
+        test.done();
+    }
+};