Skip to content

Commit fed9f9d

Browse files
author
Wanasit Tanakitrungruang
committedDec 30, 2023
New: Support reference following a date
1 parent f00e9ef commit fed9f9d

File tree

4 files changed

+81
-6
lines changed

4 files changed

+81
-6
lines changed
 

‎src/locales/en/configuration.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import ENRelativeDateFormatParser from "./parsers/ENRelativeDateFormatParser";
2020

2121
import SlashDateFormatParser from "../../common/parsers/SlashDateFormatParser";
2222
import ENTimeUnitCasualRelativeFormatParser from "./parsers/ENTimeUnitCasualRelativeFormatParser";
23-
import ENMergeRelativeDateRefiner from "./refiners/ENMergeRelativeDateRefiner";
23+
import ENMergeRelativeAfterDateRefiner from "./refiners/ENMergeRelativeAfterDateRefiner";
24+
import ENMergeRelativeFollowByDateRefiner from "./refiners/ENMergeRelativeFollowByDateRefiner";
25+
import OverlapRemovalRefiner from "../../common/refiners/OverlapRemovalRefiner";
2426

2527
export default class ENDefaultConfiguration {
2628
/**
@@ -58,10 +60,15 @@ export default class ENDefaultConfiguration {
5860
new ENTimeUnitAgoFormatParser(strictMode),
5961
new ENTimeUnitLaterFormatParser(strictMode),
6062
],
61-
refiners: [new ENMergeRelativeDateRefiner(), new ENMergeDateTimeRefiner()],
63+
refiners: [new ENMergeDateTimeRefiner()],
6264
},
6365
strictMode
6466
);
67+
// These relative-dates consideration should be done before other common refiners.
68+
options.refiners.unshift(new ENMergeRelativeFollowByDateRefiner());
69+
options.refiners.unshift(new ENMergeRelativeAfterDateRefiner());
70+
options.refiners.unshift(new OverlapRemovalRefiner());
71+
6572
// Re-apply the date time refiner again after the timezone refinement and exclusion in common refiners.
6673
options.refiners.push(new ENMergeDateTimeRefiner());
6774
// Keep the date range refiner at the end (after all other refinements).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { MergingRefiner } from "../../../common/abstractRefiners";
2+
import { ParsingComponents, ParsingResult, ReferenceWithTimezone } from "../../../results";
3+
import { parseTimeUnits } from "../constants";
4+
import { reverseTimeUnits } from "../../../utils/timeunits";
5+
6+
function IsPositiveFollowingReference(result: ParsingResult): boolean {
7+
return result.text.match(/^[+-]/i) != null;
8+
}
9+
10+
function IsNegativeFollowingReference(result: ParsingResult): boolean {
11+
return result.text.match(/^-/i) != null;
12+
}
13+
14+
/**
15+
* Merges a relative data/time that comes after an absolute date.
16+
* - [2020-02-13] [+2 weeks]
17+
* - [next tuesday] [+10 days]
18+
*/
19+
export default class ENMergeRelativeAfterDateRefiner extends MergingRefiner {
20+
shouldMergeResults(textBetween: string, currentResult: ParsingResult, nextResult: ParsingResult): boolean {
21+
if (!textBetween.match(/^\s*$/i)) {
22+
return false;
23+
}
24+
25+
return IsPositiveFollowingReference(nextResult) || IsNegativeFollowingReference(nextResult);
26+
}
27+
28+
mergeResults(textBetween: string, currentResult: ParsingResult, nextResult: ParsingResult, context): ParsingResult {
29+
let timeUnits = parseTimeUnits(nextResult.text);
30+
if (IsNegativeFollowingReference(nextResult)) {
31+
timeUnits = reverseTimeUnits(timeUnits);
32+
}
33+
34+
const components = ParsingComponents.createRelativeFromReference(
35+
new ReferenceWithTimezone(currentResult.start.date()),
36+
timeUnits
37+
);
38+
39+
return new ParsingResult(
40+
currentResult.reference,
41+
currentResult.index,
42+
`${currentResult.text}${textBetween}${nextResult.text}`,
43+
components
44+
);
45+
}
46+
}

‎src/locales/en/refiners/ENMergeRelativeDateRefiner.ts renamed to ‎src/locales/en/refiners/ENMergeRelativeFollowByDateRefiner.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ function hasImpliedLaterReferenceDate(result: ParsingResult): boolean {
1212
}
1313

1414
/**
15-
* Merges an absolute date with a relative date.
16-
* - 2 weeks before 2020-02-13
17-
* - 2 days after next Friday
15+
* Merges a relative data/time that follow by an absolute date.
16+
* - [2 weeks before] [2020-02-13]
17+
* - [2 days after] [next Friday]
1818
*/
19-
export default class ENMergeRelativeDateRefiner extends MergingRefiner {
19+
export default class ENMergeRelativeFollowByDateRefiner extends MergingRefiner {
2020
patternBetween(): RegExp {
2121
return /^\s*$/i;
2222
}

‎test/en/en_time_units_later.test.ts

+22
Original file line numberDiff line numberDiff line change
@@ -320,3 +320,25 @@ test("Test - After with reference", () => {
320320
expect(result.start.get("day")).toBe(18);
321321
});
322322
});
323+
324+
test("Test - Plus after reference", () => {
325+
testSingleCase(chrono, "next tuesday +10 days", new Date(2023, 12 - 1, 29), (result) => {
326+
expect(result.start.get("year")).toBe(2024);
327+
expect(result.start.get("month")).toBe(1);
328+
expect(result.start.get("day")).toBe(12);
329+
});
330+
331+
testSingleCase(chrono, "2023-12-29 -10days", new Date(2023, 12 - 1, 29), (result) => {
332+
expect(result.start.get("year")).toBe(2023);
333+
expect(result.start.get("month")).toBe(12);
334+
expect(result.start.get("day")).toBe(19);
335+
});
336+
337+
testSingleCase(chrono, "now + 40minutes", new Date(2023, 12 - 1, 29, 8, 30), (result) => {
338+
expect(result.start.get("year")).toBe(2023);
339+
expect(result.start.get("month")).toBe(12);
340+
expect(result.start.get("day")).toBe(29);
341+
expect(result.start.get("hour")).toBe(9);
342+
expect(result.start.get("minute")).toBe(10);
343+
});
344+
});

0 commit comments

Comments
 (0)
Please sign in to comment.