From 33e1c6817229a3392678a78bc5f1ca392bb0f656 Mon Sep 17 00:00:00 2001 From: Iskren Chernev Date: Sat, 26 Apr 2014 12:52:01 -0700 Subject: [PATCH] Better bubbling of days to years in duration --- moment.js | 19 ++++++++++++---- test/moment/duration.js | 34 ++++++++++++++++------------ test/moment/duration_from_moments.js | 2 +- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/moment.js b/moment.js index f2604d825..ff6641d39 100644 --- a/moment.js +++ b/moment.js @@ -2451,7 +2451,7 @@ days = this._days, months = this._months, data = this._data, - seconds, minutes, hours, years; + seconds, minutes, hours, years = 0; // The following code bubbles up values, see the tests for // examples of what that means. @@ -2467,12 +2467,23 @@ data.hours = hours % 24; days += absRound(hours / 24); - data.days = days % 30; + // Accurately convert days to years, assume start from year 0. + years = absRound(days * 400 / 146097); + days -= years * 365 + absRound(years / 4) - + absRound(years / 100) + absRound(years / 400); + + // 30 days to a month + // TODO (iskren): Use anchor date (like 1st Jan) to compute this. months += absRound(days / 30); - data.months = months % 12; + days %= 30; + + // 12 months -> 1 year + years += absRound(months / 12); + months %= 12; - years = absRound(months / 12); + data.days = days; + data.months = months; data.years = years; }, diff --git a/test/moment/duration.js b/test/moment/duration.js index 084a3db3c..39673d8d5 100644 --- a/test/moment/duration.js +++ b/test/moment/duration.js @@ -243,24 +243,30 @@ exports.duration = { }, "instatiation from serialized C# TimeSpan maxValue" : function (test) { - test.expect(6); - test.equal(moment.duration("10675199.02:48:05.4775807").years(), 29653, "29653 years"); - test.equal(moment.duration("10675199.02:48:05.4775807").days(), 29, "29 day"); - test.equal(moment.duration("10675199.02:48:05.4775807").hours(), 2, "2 hours"); - test.equal(moment.duration("10675199.02:48:05.4775807").minutes(), 48, "48 minutes"); - test.equal(moment.duration("10675199.02:48:05.4775807").seconds(), 5, "5 seconds"); - test.equal(moment.duration("10675199.02:48:05.4775807").milliseconds(), 477, "477 milliseconds"); + var d = moment.duration("10675199.02:48:05.4775807"); + + test.equal(d.years(), 29227, "29227 years"); + test.equal(d.months(), 8, "8 months"); + test.equal(d.days(), 17, "17 day"); // this should be 13 + + test.equal(d.hours(), 2, "2 hours"); + test.equal(d.minutes(), 48, "48 minutes"); + test.equal(d.seconds(), 5, "5 seconds"); + test.equal(d.milliseconds(), 477, "477 milliseconds"); test.done(); }, "instatiation from serialized C# TimeSpan minValue" : function (test) { - test.expect(6); - test.equal(moment.duration("-10675199.02:48:05.4775808").years(), -29653, "29653 years"); - test.equal(moment.duration("-10675199.02:48:05.4775808").days(), -29, "29 day"); - test.equal(moment.duration("-10675199.02:48:05.4775808").hours(), -2, "2 hours"); - test.equal(moment.duration("-10675199.02:48:05.4775808").minutes(), -48, "48 minutes"); - test.equal(moment.duration("-10675199.02:48:05.4775808").seconds(), -5, "5 seconds"); - test.equal(moment.duration("-10675199.02:48:05.4775808").milliseconds(), -477, "477 milliseconds"); + var d = moment.duration("-10675199.02:48:05.4775808"); + + test.equal(d.years(), -29227, "29653 years"); + test.equal(d.months(), -8, "8 day"); + test.equal(d.days(), -17, "17 day"); // this should be 13 + + test.equal(d.hours(), -2, "2 hours"); + test.equal(d.minutes(), -48, "48 minutes"); + test.equal(d.seconds(), -5, "5 seconds"); + test.equal(d.milliseconds(), -477, "477 milliseconds"); test.done(); }, diff --git a/test/moment/duration_from_moments.js b/test/moment/duration_from_moments.js index 71d0f98b0..268797558 100644 --- a/test/moment/duration_from_moments.js +++ b/test/moment/duration_from_moments.js @@ -1,6 +1,6 @@ var moment = require("../../moment"); -exports.duration_from_moments = { +exports.durationFromMoments = { setUp: function (done) { moment.createFromInputFallback = function () { throw new Error("input not handled by moment"); -- 2.47.2