From 31bcae3674cccc50a38293828c3fe69f83674c60 Mon Sep 17 00:00:00 2001 From: Wanasit Tanakitrungruang Date: Mon, 16 Sep 2024 14:12:38 +0900 Subject: [PATCH] Fix: Forward dates option affect relative timeago results --- src/common/refiners/ForwardDateRefiner.ts | 13 ++++++---- src/results.ts | 13 ++++++---- test/en/en_merging_relative_dates.test.ts | 7 +++-- test/en/en_time_units_ago.test.ts | 31 +++++++++++++++++++++++ 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/common/refiners/ForwardDateRefiner.ts b/src/common/refiners/ForwardDateRefiner.ts index 3825e556..fafa2ce0 100644 --- a/src/common/refiners/ForwardDateRefiner.ts +++ b/src/common/refiners/ForwardDateRefiner.ts @@ -15,7 +15,7 @@ export default class ForwardDateRefiner implements Refiner { return results; } - results.forEach(function (result) { + results.forEach((result) => { let refMoment = dayjs(context.refDate); if (result.start.isOnlyTime() && refMoment.isAfter(result.start.dayjs())) { @@ -28,6 +28,9 @@ export default class ForwardDateRefiner implements Refiner { implySimilarDate(result.end, refMoment); } } + context.debug(() => { + console.log(`${this.constructor.name} adjusted ${result} time result (${result.start})`); + }); } if (result.start.isOnlyWeekdayComponent() && refMoment.isAfter(result.start.dayjs())) { @@ -41,7 +44,7 @@ export default class ForwardDateRefiner implements Refiner { result.start.imply("month", refMoment.month() + 1); result.start.imply("year", refMoment.year()); context.debug(() => { - console.log(`Forward weekly adjusted for ${result} (${result.start})`); + console.log(`${this.constructor.name} adjusted ${result} weekday (${result.start})`); }); if (result.end && result.end.isOnlyWeekdayComponent()) { @@ -56,7 +59,7 @@ export default class ForwardDateRefiner implements Refiner { result.end.imply("month", refMoment.month() + 1); result.end.imply("year", refMoment.year()); context.debug(() => { - console.log(`Forward weekly adjusted for ${result} (${result.end})`); + console.log(`${this.constructor.name} adjusted ${result} weekday (${result.end})`); }); } } @@ -67,13 +70,13 @@ export default class ForwardDateRefiner implements Refiner { for (let i = 0; i < 3 && refMoment.isAfter(result.start.dayjs()); i++) { result.start.imply("year", result.start.get("year") + 1); context.debug(() => { - console.log(`Forward yearly adjusted for ${result} (${result.start})`); + console.log(`${this.constructor.name} adjusted ${result} year (${result.start})`); }); if (result.end && !result.end.isCertain("year")) { result.end.imply("year", result.end.get("year") + 1); context.debug(() => { - console.log(`Forward yearly adjusted for ${result} (${result.end})`); + console.log(`${this.constructor.name} adjusted ${result} month (${result.start})`); }); } } diff --git a/src/results.ts b/src/results.ts index ef6f8ed6..a2aa31fd 100644 --- a/src/results.ts +++ b/src/results.ts @@ -132,7 +132,9 @@ export class ParsingComponents implements ParsedComponents { } isOnlyTime(): boolean { - return !this.isCertain("weekday") && !this.isCertain("day") && !this.isCertain("month"); + return ( + !this.isCertain("weekday") && !this.isCertain("day") && !this.isCertain("month") && !this.isCertain("year") + ); } isOnlyWeekdayComponent(): boolean { @@ -230,11 +232,12 @@ export class ParsingComponents implements ParsedComponents { components.assign("day", date.date()); components.assign("month", date.month() + 1); components.assign("year", date.year()); + } else if (fragments["week"]) { + components.assign("day", date.date()); + components.assign("month", date.month() + 1); + components.assign("year", date.year()); + components.imply("weekday", date.day()); } else { - if (fragments["week"]) { - components.imply("weekday", date.day()); - } - components.imply("day", date.date()); if (fragments["month"]) { components.assign("month", date.month() + 1); diff --git a/test/en/en_merging_relative_dates.test.ts b/test/en/en_merging_relative_dates.test.ts index 6505e737..be31633c 100644 --- a/test/en/en_merging_relative_dates.test.ts +++ b/test/en/en_merging_relative_dates.test.ts @@ -11,10 +11,9 @@ test("Test - Single Expression", function () { expect(result.start.get("day")).toBe(15); expect(result.start.get("weekday")).toBe(2); - expect(result.start.isCertain("day")).toBe(false); - expect(result.start.isCertain("month")).toBe(false); - expect(result.start.isCertain("year")).toBe(false); - expect(result.start.isCertain("weekday")).toBe(false); + expect(result.start.isCertain("day")).toBe(true); + expect(result.start.isCertain("month")).toBe(true); + expect(result.start.isCertain("year")).toBe(true); expect(result.start).toBeDate(new Date(2022, 2 - 1, 15, 0)); }); diff --git a/test/en/en_time_units_ago.test.ts b/test/en/en_time_units_ago.test.ts index 889c1d0c..096900f6 100644 --- a/test/en/en_time_units_ago.test.ts +++ b/test/en/en_time_units_ago.test.ts @@ -312,6 +312,37 @@ test("Test - Strict mode", function () { testUnexpectedResult(chrono.strict, "5 h ago", new Date(2012, 7, 10, 12, 14)); }); +test("Test - Forward date", () => { + // Note that it is actually impossible for X ago to be "forward dates". + // In such situation, we still return the correct actual extracted dates and make sure the option doesn't affect the results. + const reference = new Date("2024-09-10T12:00:00"); + const options = { forwardDate: true }; + + testSingleCase(chrono, "2 days ago", reference, options, (result, text) => { + expect(result.start.get("year")).toBe(2024); + expect(result.start.get("month")).toBe(9); + expect(result.start.get("day")).toBe(8); + }); + + testSingleCase(chrono, "2 weeks ago", reference, options, (result, text) => { + expect(result.start.get("year")).toBe(2024); + expect(result.start.get("month")).toBe(8); + expect(result.start.get("day")).toBe(27); + }); + + testSingleCase(chrono, "2 months ago", reference, options, (result, text) => { + expect(result.start.get("year")).toBe(2024); + expect(result.start.get("month")).toBe(7); + expect(result.start.get("day")).toBe(10); + }); + + testSingleCase(chrono, "2 years ago", reference, options, (result, text) => { + expect(result.start.get("year")).toBe(2022); + expect(result.start.get("month")).toBe(9); + expect(result.start.get("day")).toBe(10); + }); +}); + test("Test - Negative cases", function () { testUnexpectedResult(chrono, "15 hours 29 min"); testUnexpectedResult(chrono, "a few hour");