From f8285c74f38d59ad3bd0d7fc91ef3a9d51571270 Mon Sep 17 00:00:00 2001 From: dobon Date: Tue, 6 Dec 2022 07:23:45 -0800 Subject: [PATCH] find diff by duration hash instead of using repeated addition to cursor (#1340) --- src/impl/diff.js | 11 +++++------ test/datetime/diff.test.js | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/impl/diff.js b/src/impl/diff.js index fc11678bc..7fe389b6e 100644 --- a/src/impl/diff.js +++ b/src/impl/diff.js @@ -22,23 +22,22 @@ function highOrderDiffs(cursor, later, units) { ]; const results = {}; + const earlier = cursor; let lowestOrder, highWater; for (const [unit, differ] of differs) { if (units.indexOf(unit) >= 0) { lowestOrder = unit; - let delta = differ(cursor, later); - highWater = cursor.plus({ [unit]: delta }); + results[unit] = differ(cursor, later); + highWater = earlier.plus(results); if (highWater > later) { - cursor = cursor.plus({ [unit]: delta - 1 }); - delta -= 1; + results[unit]--; + cursor = earlier.plus(results); } else { cursor = highWater; } - - results[unit] = delta; } } diff --git a/test/datetime/diff.test.js b/test/datetime/diff.test.js index 3f0eeba28..d94725452 100644 --- a/test/datetime/diff.test.js +++ b/test/datetime/diff.test.js @@ -295,14 +295,24 @@ test("DateTime#diff results in a duration with the same locale", () => { // see https://github.com/moment/luxon/issues/487 test("DateTime#diff results works when needing to backtrack months", () => { - const left = DateTime.fromJSDate(new Date(1554036127038)); - const right = DateTime.fromJSDate(new Date(1554122527128)); + const left = DateTime.fromJSDate(new Date(1554036127038)); // 2019-03-31T12:42:07.038Z + const right = DateTime.fromJSDate(new Date(1554122527128)); // 2019-04-01T12:42:07.128Z const diff = right.diff(left, ["months", "days", "hours"]); expect(diff.months).toBe(0); expect(diff.days).toBe(1); }); +// see https://github.com/moment/luxon/issues/1301 +test("DateTime#diff handles Feb-29 edge case logic for higher order units in a manner consistent with DateTime#plus", () => { + const left = DateTime.fromISO("2020-02-29"); + const right = DateTime.fromISO("2021-04-01"); + + const diff = right.diff(left, ["years", "months", "days"]); + expect(diff.days).toBe(3); + expect(left.plus(diff).equals(right)).toBe(true); +}); + //------ // diffNow //-------