chrono-node 2.10.1 → 2.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/calculation/duration.js +12 -7
- package/dist/cjs/calculation/duration.js.map +1 -1
- package/dist/cjs/common/refiners/AbstractMergeDateTimeRefiner.js +6 -3
- package/dist/cjs/common/refiners/AbstractMergeDateTimeRefiner.js.map +1 -1
- package/dist/cjs/common/refiners/MergeWeekdayComponentRefiner.js +2 -1
- package/dist/cjs/common/refiners/MergeWeekdayComponentRefiner.js.map +1 -1
- package/dist/cjs/locales/en/configuration.js +4 -0
- package/dist/cjs/locales/en/configuration.js.map +1 -1
- package/dist/cjs/locales/en/parsers/ENEndOfCurrentMonthParser.d.ts +7 -0
- package/dist/cjs/locales/en/parsers/ENEndOfCurrentMonthParser.js +23 -0
- package/dist/cjs/locales/en/parsers/ENEndOfCurrentMonthParser.js.map +1 -0
- package/dist/cjs/locales/en/parsers/ENSlashMonthFormatParser.d.ts +1 -1
- package/dist/cjs/locales/en/parsers/ENSlashMonthFormatParser.js +3 -0
- package/dist/cjs/locales/en/parsers/ENSlashMonthFormatParser.js.map +1 -1
- package/dist/cjs/locales/en/parsers/ENTimeUnitWithinFormatParser.js +1 -1
- package/dist/cjs/locales/en/parsers/ENTimeUnitWithinFormatParser.js.map +1 -1
- package/dist/cjs/locales/en/refiners/ENEndOfPeriodRefiner.d.ts +7 -0
- package/dist/cjs/locales/en/refiners/ENEndOfPeriodRefiner.js +81 -0
- package/dist/cjs/locales/en/refiners/ENEndOfPeriodRefiner.js.map +1 -0
- package/dist/cjs/locales/zh/hans/parsers/ZHHansAgoFormatParser.d.ts +1 -0
- package/dist/cjs/locales/zh/hans/parsers/ZHHansAgoFormatParser.js +3 -0
- package/dist/cjs/locales/zh/hans/parsers/ZHHansAgoFormatParser.js.map +1 -1
- package/dist/cjs/locales/zh/hans/parsers/ZHHansDateParser.d.ts +1 -0
- package/dist/cjs/locales/zh/hans/parsers/ZHHansDateParser.js +3 -0
- package/dist/cjs/locales/zh/hans/parsers/ZHHansDateParser.js.map +1 -1
- package/dist/cjs/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.d.ts +1 -0
- package/dist/cjs/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.js +3 -0
- package/dist/cjs/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.js.map +1 -1
- package/dist/cjs/locales/zh/hant/parsers/ZHHantAgoFormatParser.d.ts +1 -0
- package/dist/cjs/locales/zh/hant/parsers/ZHHantAgoFormatParser.js +3 -0
- package/dist/cjs/locales/zh/hant/parsers/ZHHantAgoFormatParser.js.map +1 -1
- package/dist/cjs/locales/zh/hant/parsers/ZHHantDateParser.d.ts +1 -0
- package/dist/cjs/locales/zh/hant/parsers/ZHHantDateParser.js +3 -0
- package/dist/cjs/locales/zh/hant/parsers/ZHHantDateParser.js.map +1 -1
- package/dist/cjs/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.d.ts +1 -0
- package/dist/cjs/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.js +3 -0
- package/dist/cjs/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.js.map +1 -1
- package/dist/esm/calculation/duration.js +5 -0
- package/dist/esm/calculation/duration.js.map +1 -1
- package/dist/esm/common/refiners/AbstractMergeDateTimeRefiner.js +6 -3
- package/dist/esm/common/refiners/AbstractMergeDateTimeRefiner.js.map +1 -1
- package/dist/esm/common/refiners/MergeWeekdayComponentRefiner.js +2 -1
- package/dist/esm/common/refiners/MergeWeekdayComponentRefiner.js.map +1 -1
- package/dist/esm/locales/en/configuration.js +4 -0
- package/dist/esm/locales/en/configuration.js.map +1 -1
- package/dist/esm/locales/en/parsers/ENEndOfCurrentMonthParser.d.ts +7 -0
- package/dist/esm/locales/en/parsers/ENEndOfCurrentMonthParser.js +20 -0
- package/dist/esm/locales/en/parsers/ENEndOfCurrentMonthParser.js.map +1 -0
- package/dist/esm/locales/en/parsers/ENSlashMonthFormatParser.d.ts +1 -1
- package/dist/esm/locales/en/parsers/ENSlashMonthFormatParser.js +3 -0
- package/dist/esm/locales/en/parsers/ENSlashMonthFormatParser.js.map +1 -1
- package/dist/esm/locales/en/parsers/ENTimeUnitWithinFormatParser.js +1 -1
- package/dist/esm/locales/en/parsers/ENTimeUnitWithinFormatParser.js.map +1 -1
- package/dist/esm/locales/en/refiners/ENEndOfPeriodRefiner.d.ts +7 -0
- package/dist/esm/locales/en/refiners/ENEndOfPeriodRefiner.js +78 -0
- package/dist/esm/locales/en/refiners/ENEndOfPeriodRefiner.js.map +1 -0
- package/dist/esm/locales/zh/hans/parsers/ZHHansAgoFormatParser.d.ts +1 -0
- package/dist/esm/locales/zh/hans/parsers/ZHHansAgoFormatParser.js +3 -0
- package/dist/esm/locales/zh/hans/parsers/ZHHansAgoFormatParser.js.map +1 -1
- package/dist/esm/locales/zh/hans/parsers/ZHHansDateParser.d.ts +1 -0
- package/dist/esm/locales/zh/hans/parsers/ZHHansDateParser.js +3 -0
- package/dist/esm/locales/zh/hans/parsers/ZHHansDateParser.js.map +1 -1
- package/dist/esm/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.d.ts +1 -0
- package/dist/esm/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.js +3 -0
- package/dist/esm/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.js.map +1 -1
- package/dist/esm/locales/zh/hant/parsers/ZHHantAgoFormatParser.d.ts +1 -0
- package/dist/esm/locales/zh/hant/parsers/ZHHantAgoFormatParser.js +3 -0
- package/dist/esm/locales/zh/hant/parsers/ZHHantAgoFormatParser.js.map +1 -1
- package/dist/esm/locales/zh/hant/parsers/ZHHantDateParser.d.ts +1 -0
- package/dist/esm/locales/zh/hant/parsers/ZHHantDateParser.js +3 -0
- package/dist/esm/locales/zh/hant/parsers/ZHHantDateParser.js.map +1 -1
- package/dist/esm/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.d.ts +1 -0
- package/dist/esm/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.js +3 -0
- package/dist/esm/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.js.map +1 -1
- package/package.json +1 -1
- package/src/calculation/duration.ts +5 -0
- package/src/common/refiners/AbstractMergeDateTimeRefiner.ts +13 -5
- package/src/common/refiners/MergeWeekdayComponentRefiner.ts +6 -1
- package/src/locales/en/configuration.ts +4 -0
- package/src/locales/en/parsers/ENEndOfCurrentMonthParser.ts +25 -0
- package/src/locales/en/parsers/ENSlashMonthFormatParser.ts +7 -1
- package/src/locales/en/parsers/ENTimeUnitWithinFormatParser.ts +1 -1
- package/src/locales/en/refiners/ENEndOfPeriodRefiner.ts +101 -0
- package/src/locales/zh/hans/parsers/ZHHansAgoFormatParser.ts +6 -0
- package/src/locales/zh/hans/parsers/ZHHansDateParser.ts +6 -0
- package/src/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.ts +6 -0
- package/src/locales/zh/hant/parsers/ZHHantAgoFormatParser.ts +6 -0
- package/src/locales/zh/hant/parsers/ZHHantDateParser.ts +6 -0
- package/src/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.ts +6 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ParsingContext } from "../../../chrono";
|
|
2
|
+
import { ParsingComponents } from "../../../results";
|
|
3
|
+
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
|
|
4
|
+
|
|
5
|
+
const PATTERN = /(?:last\s+day|end)\s+of\s+(?:the\s+)?month(?=\W|$)/i;
|
|
6
|
+
|
|
7
|
+
export default class ENEndOfCurrentMonthParser extends AbstractParserWithWordBoundaryChecking {
|
|
8
|
+
innerPattern(): RegExp {
|
|
9
|
+
return PATTERN;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
innerExtract(context: ParsingContext): ParsingComponents {
|
|
13
|
+
const targetDate = context.reference.getDateWithAdjustedTimezone();
|
|
14
|
+
const year = targetDate.getFullYear();
|
|
15
|
+
const month = targetDate.getMonth() + 1;
|
|
16
|
+
const lastDay = new Date(year, month, 0).getDate();
|
|
17
|
+
const components = context.createParsingComponents();
|
|
18
|
+
|
|
19
|
+
components.assign("day", lastDay);
|
|
20
|
+
components.assign("month", month);
|
|
21
|
+
components.assign("year", year);
|
|
22
|
+
components.addTag("parser/ENEndOfCurrentMonthParser");
|
|
23
|
+
return components;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -17,7 +17,13 @@ export default class ENSlashMonthFormatParser extends AbstractParserWithWordBoun
|
|
|
17
17
|
return PATTERN;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
|
|
20
|
+
innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents | null {
|
|
21
|
+
// Do not extract a month/year suffix from an invalid numeric date (e.g. "50/6/2018").
|
|
22
|
+
// Parsing can also resume within a rejected match, so check the original text.
|
|
23
|
+
if (/\d\/?$/.test(context.text.substring(0, match.index))) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
21
27
|
const year = parseInt(match[YEAR_GROUP]);
|
|
22
28
|
const month = parseInt(match[MONTH_GROUP]);
|
|
23
29
|
|
|
@@ -35,7 +35,7 @@ export default class ENTimeUnitWithinFormatParser extends AbstractParserWithWord
|
|
|
35
35
|
|
|
36
36
|
innerExtract(context: ParsingContext, match: RegExpMatchArray) {
|
|
37
37
|
// Exclude "for the unit" phases, e.g. "for the year"
|
|
38
|
-
if (match[0].match(/^for\s*the\s*\w+/)) {
|
|
38
|
+
if (match[0].match(/^for\s*the\s*\w+/i)) {
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
41
|
const timeUnits = parseDuration(match[1]);
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { ParsingContext, Refiner } from "../../../chrono";
|
|
2
|
+
import { ParsingResult } from "../../../results";
|
|
3
|
+
import { findYearClosestToRef } from "../../../calculation/years";
|
|
4
|
+
|
|
5
|
+
const PREFIX_PATTERN = /\b(?:last\s+day|end)\s+of\s+(?:the\s+)?$/i;
|
|
6
|
+
const RELATIVE_PERIOD_PATTERN = /^(this|last|past|next)\s*(week|month|year)$/i;
|
|
7
|
+
const RELATIVE_YEAR_SUFFIX_PATTERN = /^\s+(this|last|past|next)\s+year(?=\W|$)/i;
|
|
8
|
+
|
|
9
|
+
function modifierOffset(modifier: string): number {
|
|
10
|
+
return modifier === "next" ? 1 : modifier === "last" || modifier === "past" ? -1 : 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Moves a result preceded by "end of" or "last day of" to the last day of its period.
|
|
15
|
+
* A relative period ("next week", "this year") comes from the relative parsers. Its end follows from the reference
|
|
16
|
+
* date and the modifier alone, so it is computed from those rather than from the day the relative parser picked.
|
|
17
|
+
* A named month ("July", "February 2024") has a certain month and no certain day.
|
|
18
|
+
*/
|
|
19
|
+
export default class ENEndOfPeriodRefiner implements Refiner {
|
|
20
|
+
refine(context: ParsingContext, results: ParsingResult[]): ParsingResult[] {
|
|
21
|
+
results.forEach((result) => {
|
|
22
|
+
const prefix = context.text.substring(0, result.index).match(PREFIX_PATTERN);
|
|
23
|
+
if (!prefix) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const relativePeriod = result.text.match(RELATIVE_PERIOD_PATTERN);
|
|
28
|
+
if (relativePeriod) {
|
|
29
|
+
const modifier = relativePeriod[1].toLowerCase();
|
|
30
|
+
this.moveToEndOfRelativePeriod(context, result, modifier, relativePeriod[2].toLowerCase());
|
|
31
|
+
} else if (result.start.isCertain("month") && !result.start.isCertain("day")) {
|
|
32
|
+
this.moveToEndOfMonth(context, result);
|
|
33
|
+
} else {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// The relative parsers imply the reference time and UTC offset, but the end of a period is a whole day
|
|
38
|
+
// like a named month, and the reference offset is wrong when a DST change lies in between
|
|
39
|
+
result.start.imply("hour", 12);
|
|
40
|
+
result.start.imply("minute", 0);
|
|
41
|
+
result.start.imply("second", 0);
|
|
42
|
+
result.start.imply("millisecond", 0);
|
|
43
|
+
if (!result.start.isCertain("timezoneOffset")) {
|
|
44
|
+
result.start.delete("timezoneOffset");
|
|
45
|
+
}
|
|
46
|
+
result.index -= prefix[0].length;
|
|
47
|
+
result.text = prefix[0] + result.text;
|
|
48
|
+
result.addTag("refiner/ENEndOfPeriodRefiner");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return results;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private moveToEndOfRelativePeriod(
|
|
55
|
+
context: ParsingContext,
|
|
56
|
+
result: ParsingResult,
|
|
57
|
+
modifier: string,
|
|
58
|
+
period: string
|
|
59
|
+
) {
|
|
60
|
+
const offset = modifierOffset(modifier);
|
|
61
|
+
const referenceDate = context.reference.getDateWithAdjustedTimezone();
|
|
62
|
+
let lastDay: Date;
|
|
63
|
+
|
|
64
|
+
if (period === "week") {
|
|
65
|
+
lastDay = new Date(referenceDate.getTime());
|
|
66
|
+
lastDay.setDate(referenceDate.getDate() + (6 - referenceDate.getDay()) + offset * 7);
|
|
67
|
+
} else if (period === "month") {
|
|
68
|
+
lastDay = new Date(referenceDate.getFullYear(), referenceDate.getMonth() + offset + 1, 0);
|
|
69
|
+
} else {
|
|
70
|
+
lastDay = new Date(referenceDate.getFullYear() + offset, 11, 31);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
result.start.assign("day", lastDay.getDate());
|
|
74
|
+
result.start.assign("month", lastDay.getMonth() + 1);
|
|
75
|
+
result.start.assign("year", lastDay.getFullYear());
|
|
76
|
+
result.start.delete("weekday");
|
|
77
|
+
result.start.imply("weekday", lastDay.getDay());
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private moveToEndOfMonth(context: ParsingContext, result: ParsingResult) {
|
|
81
|
+
let year = result.start.get("year");
|
|
82
|
+
const month = result.start.get("month");
|
|
83
|
+
const suffix = context.text.substring(result.index + result.text.length).match(RELATIVE_YEAR_SUFFIX_PATTERN);
|
|
84
|
+
|
|
85
|
+
if (suffix) {
|
|
86
|
+
const modifier = suffix[1].toLowerCase();
|
|
87
|
+
const referenceYear = context.reference.getDateWithAdjustedTimezone().getFullYear();
|
|
88
|
+
year = referenceYear + modifierOffset(modifier);
|
|
89
|
+
result.start.assign("year", year);
|
|
90
|
+
result.text += suffix[0];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!result.start.isCertain("year")) {
|
|
94
|
+
const lastDayInReferenceYear = new Date(year, month, 0).getDate();
|
|
95
|
+
year = findYearClosestToRef(context.reference.getDateWithAdjustedTimezone(), lastDayInReferenceYear, month);
|
|
96
|
+
result.start.imply("year", year);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
result.start.assign("day", new Date(year, month, 0).getDate());
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -17,6 +17,12 @@ const NUMBER_GROUP = 1;
|
|
|
17
17
|
const UNIT_GROUP = 2;
|
|
18
18
|
|
|
19
19
|
export default class ZHHansAgoFormatParser extends AbstractParserWithWordBoundaryChecking {
|
|
20
|
+
patternLeftBoundary(): string {
|
|
21
|
+
// Return a capturing group to ensure that the match index is correct in the base class
|
|
22
|
+
// while avoiding matching CJK characters as word boundaries.
|
|
23
|
+
return "()";
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
innerPattern(): RegExp {
|
|
21
27
|
return PATTERN;
|
|
22
28
|
}
|
|
@@ -7,6 +7,12 @@ const MONTH_GROUP = 2;
|
|
|
7
7
|
const DAY_GROUP = 3;
|
|
8
8
|
|
|
9
9
|
export default class ZHHansDateParser extends AbstractParserWithWordBoundaryChecking {
|
|
10
|
+
patternLeftBoundary(): string {
|
|
11
|
+
// Return a capturing group to ensure that the match index is correct in the base class
|
|
12
|
+
// while avoiding matching CJK characters as word boundaries.
|
|
13
|
+
return "()";
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
innerPattern() {
|
|
11
17
|
// prettier-ignore
|
|
12
18
|
return new RegExp(
|
|
@@ -17,6 +17,12 @@ const NUMBER_GROUP = 1;
|
|
|
17
17
|
const UNIT_GROUP = 2;
|
|
18
18
|
|
|
19
19
|
export default class ZHHansDeadlineFormatParser extends AbstractParserWithWordBoundaryChecking {
|
|
20
|
+
patternLeftBoundary(): string {
|
|
21
|
+
// Return a capturing group to ensure that the match index is correct in the base class
|
|
22
|
+
// while avoiding matching CJK characters as word boundaries.
|
|
23
|
+
return "()";
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
innerPattern(): RegExp {
|
|
21
27
|
return PATTERN;
|
|
22
28
|
}
|
|
@@ -17,6 +17,12 @@ const NUMBER_GROUP = 1;
|
|
|
17
17
|
const UNIT_GROUP = 2;
|
|
18
18
|
|
|
19
19
|
export default class ZHHantAgoFormatParser extends AbstractParserWithWordBoundaryChecking {
|
|
20
|
+
patternLeftBoundary(): string {
|
|
21
|
+
// Return a capturing group to ensure that the match index is correct in the base class
|
|
22
|
+
// while avoiding matching CJK characters as word boundaries.
|
|
23
|
+
return "()";
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
innerPattern(): RegExp {
|
|
21
27
|
return PATTERN;
|
|
22
28
|
}
|
|
@@ -7,6 +7,12 @@ const MONTH_GROUP = 2;
|
|
|
7
7
|
const DAY_GROUP = 3;
|
|
8
8
|
|
|
9
9
|
export default class ZHHantDateParser extends AbstractParserWithWordBoundaryChecking {
|
|
10
|
+
patternLeftBoundary(): string {
|
|
11
|
+
// Return a capturing group to ensure that the match index is correct in the base class
|
|
12
|
+
// while avoiding matching CJK characters as word boundaries.
|
|
13
|
+
return "()";
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
innerPattern() {
|
|
11
17
|
// prettier-ignore
|
|
12
18
|
return new RegExp(
|
|
@@ -17,6 +17,12 @@ const NUMBER_GROUP = 1;
|
|
|
17
17
|
const UNIT_GROUP = 2;
|
|
18
18
|
|
|
19
19
|
export default class ZHHantDeadlineFormatParser extends AbstractParserWithWordBoundaryChecking {
|
|
20
|
+
patternLeftBoundary(): string {
|
|
21
|
+
// Return a capturing group to ensure that the match index is correct in the base class
|
|
22
|
+
// while avoiding matching CJK characters as word boundaries.
|
|
23
|
+
return "()";
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
innerPattern(): RegExp {
|
|
21
27
|
return PATTERN;
|
|
22
28
|
}
|