chrono-node 2.2.7 → 2.3.3
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/README.md +25 -9
- package/benchmark/benchmark.js +4 -0
- package/dist/bundle.js +5047 -0
- package/dist/chrono.d.ts +7 -6
- package/dist/chrono.js +6 -5
- package/dist/common/casualReferences.d.ts +6 -6
- package/dist/common/casualReferences.js +16 -15
- package/dist/common/refiners/ForwardDateRefiner.js +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/locales/de/constants.js +1 -1
- package/dist/locales/de/parsers/DECasualDateParser.js +2 -2
- package/dist/locales/en/constants.d.ts +1 -1
- package/dist/locales/en/constants.js +5 -5
- package/dist/locales/en/parsers/ENCasualDateParser.js +5 -5
- package/dist/locales/en/parsers/ENCasualTimeParser.js +1 -1
- package/dist/locales/en/parsers/ENMonthNameLittleEndianParser.js +6 -8
- package/dist/locales/en/parsers/ENRelativeDateFormatParser.js +3 -3
- package/dist/locales/en/parsers/ENTimeUnitAgoFormatParser.js +3 -3
- package/dist/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.js +1 -1
- package/dist/locales/en/parsers/ENTimeUnitLaterFormatParser.js +2 -2
- package/dist/locales/en/parsers/ENTimeUnitWithinFormatParser.js +1 -1
- package/dist/locales/fr/constants.js +1 -1
- package/dist/locales/fr/parsers/FRCasualDateParser.js +4 -4
- package/dist/locales/fr/parsers/FRTimeUnitAgoFormatParser.js +1 -1
- package/dist/locales/fr/parsers/FRTimeUnitRelativeFormatParser.js +1 -1
- package/dist/locales/fr/parsers/FRTimeUnitWithinFormatParser.js +1 -1
- package/dist/locales/ja/parsers/JPCasualDateParser.js +3 -3
- package/dist/locales/nl/constants.js +8 -5
- package/dist/locales/nl/index.js +12 -3
- package/dist/locales/nl/parsers/NLCasualDateParser.js +4 -4
- package/dist/locales/nl/parsers/NLRelativeDateFormatParser.d.ts +7 -0
- package/dist/locales/nl/parsers/NLRelativeDateFormatParser.js +57 -0
- package/dist/locales/nl/parsers/NLTimeExpressionParser.d.ts +1 -0
- package/dist/locales/nl/parsers/NLTimeExpressionParser.js +3 -0
- package/dist/locales/nl/parsers/NLTimeUnitAgoFormatParser.d.ts +9 -0
- package/dist/locales/nl/parsers/NLTimeUnitAgoFormatParser.js +23 -0
- package/dist/locales/nl/parsers/NLTimeUnitCasualRelativeFormatParser.d.ts +7 -0
- package/dist/locales/nl/parsers/NLTimeUnitCasualRelativeFormatParser.js +25 -0
- package/dist/locales/nl/parsers/NLTimeUnitLaterFormatParser.d.ts +9 -0
- package/dist/locales/nl/parsers/NLTimeUnitLaterFormatParser.js +22 -0
- package/dist/locales/nl/parsers/NLTimeUnitWithinFormatParser.js +1 -1
- package/dist/locales/pt/parsers/PTCasualDateParser.js +4 -4
- package/dist/main.js +1078 -0
- package/dist/results.d.ts +12 -5
- package/dist/results.js +40 -17
- package/dist/timezone.d.ts +194 -0
- package/dist/timezone.js +207 -0
- package/dist/utils/dayjs.js +0 -2
- package/dist/utils/pattern.js +1 -1
- package/package.json +3 -3
- package/src/chrono.ts +21 -8
- package/src/common/casualReferences.ts +17 -18
- package/src/common/refiners/ForwardDateRefiner.ts +1 -1
- package/src/index.ts +19 -3
- package/src/locales/de/constants.ts +1 -1
- package/src/locales/de/parsers/DECasualDateParser.ts +2 -2
- package/src/locales/en/constants.ts +5 -5
- package/src/locales/en/parsers/ENCasualDateParser.ts +5 -5
- package/src/locales/en/parsers/ENCasualTimeParser.ts +1 -1
- package/src/locales/en/parsers/ENMonthNameLittleEndianParser.ts +9 -10
- package/src/locales/en/parsers/ENRelativeDateFormatParser.ts +3 -3
- package/src/locales/en/parsers/ENTimeUnitAgoFormatParser.ts +3 -4
- package/src/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.ts +1 -1
- package/src/locales/en/parsers/ENTimeUnitLaterFormatParser.ts +2 -2
- package/src/locales/en/parsers/ENTimeUnitWithinFormatParser.ts +1 -1
- package/src/locales/fr/constants.ts +1 -1
- package/src/locales/fr/parsers/FRCasualDateParser.ts +4 -4
- package/src/locales/fr/parsers/FRTimeUnitAgoFormatParser.ts +1 -1
- package/src/locales/fr/parsers/FRTimeUnitRelativeFormatParser.ts +1 -1
- package/src/locales/fr/parsers/FRTimeUnitWithinFormatParser.ts +1 -1
- package/src/locales/ja/parsers/JPCasualDateParser.ts +3 -3
- package/src/locales/nl/constants.ts +11 -5
- package/src/locales/nl/index.ts +12 -3
- package/src/locales/nl/parsers/NLCasualDateParser.ts +4 -4
- package/src/locales/nl/parsers/NLRelativeDateFormatParser.ts +70 -0
- package/src/locales/nl/parsers/NLTimeExpressionParser.ts +4 -0
- package/src/locales/nl/parsers/NLTimeUnitAgoFormatParser.ts +26 -0
- package/src/locales/nl/parsers/NLTimeUnitCasualRelativeFormatParser.ts +27 -0
- package/src/locales/nl/parsers/NLTimeUnitLaterFormatParser.ts +27 -0
- package/src/locales/nl/parsers/NLTimeUnitWithinFormatParser.ts +1 -1
- package/src/locales/pt/parsers/PTCasualDateParser.ts +4 -4
- package/src/results.ts +52 -18
- package/src/timezone.ts +205 -0
- package/src/utils/dayjs.ts +0 -2
- package/src/utils/pattern.ts +1 -1
- package/test/en/en_month_name_little_endian.test.ts +10 -0
- package/test/en/en_relative.test.ts +30 -0
- package/test/en/en_slash.test.ts +11 -0
- package/test/en/en_timezone_exp.test.ts +7 -4
- package/test/en/en_weekday.test.ts +69 -25
- package/test/en/negative_cases.test.ts +2 -0
- package/test/nl/nl_relative.test.ts +212 -0
- package/test/nl/nl_time_units_ago.test.ts +243 -0
- package/test/nl/nl_time_units_casual_relative.test.ts +130 -0
- package/test/nl/nl_time_units_later.test.ts +250 -0
- package/test/result.test.ts +32 -13
- package/test/system_timezone.test.ts +100 -0
- package/test/test_util.ts +10 -7
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { ParsingComponents } from "../results";
|
|
1
|
+
import { ParsingComponents, ReferenceWithTimezone } from "../results";
|
|
2
2
|
import dayjs from "dayjs";
|
|
3
3
|
import { assignSimilarDate, assignSimilarTime, assignTheNextDay, implySimilarTime } from "../utils/dayjs";
|
|
4
4
|
import { Meridiem } from "../index";
|
|
5
5
|
|
|
6
|
-
export function now(
|
|
7
|
-
const targetDate = dayjs(
|
|
8
|
-
const component = new ParsingComponents(
|
|
6
|
+
export function now(reference: ReferenceWithTimezone): ParsingComponents {
|
|
7
|
+
const targetDate = dayjs(reference.instant);
|
|
8
|
+
const component = new ParsingComponents(reference, {});
|
|
9
9
|
assignSimilarDate(component, targetDate);
|
|
10
10
|
assignSimilarTime(component, targetDate);
|
|
11
|
+
component.assign("timezoneOffset", targetDate.utcOffset());
|
|
11
12
|
return component;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
export function today(
|
|
15
|
-
const targetDate = dayjs(
|
|
16
|
-
const component = new ParsingComponents(
|
|
15
|
+
export function today(reference: ReferenceWithTimezone): ParsingComponents {
|
|
16
|
+
const targetDate = dayjs(reference.instant);
|
|
17
|
+
const component = new ParsingComponents(reference, {});
|
|
17
18
|
assignSimilarDate(component, targetDate);
|
|
18
19
|
implySimilarTime(component, targetDate);
|
|
19
20
|
return component;
|
|
@@ -21,11 +22,10 @@ export function today(refDate: Date): ParsingComponents {
|
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* The previous day. Imply the same time.
|
|
24
|
-
* @param refDate
|
|
25
25
|
*/
|
|
26
|
-
export function yesterday(
|
|
27
|
-
let targetDate = dayjs(
|
|
28
|
-
const component = new ParsingComponents(
|
|
26
|
+
export function yesterday(reference: ReferenceWithTimezone): ParsingComponents {
|
|
27
|
+
let targetDate = dayjs(reference.instant);
|
|
28
|
+
const component = new ParsingComponents(reference, {});
|
|
29
29
|
targetDate = targetDate.add(-1, "day");
|
|
30
30
|
assignSimilarDate(component, targetDate);
|
|
31
31
|
implySimilarTime(component, targetDate);
|
|
@@ -34,18 +34,17 @@ export function yesterday(refDate: Date): ParsingComponents {
|
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* The following day with dayjs.assignTheNextDay()
|
|
37
|
-
* @param refDate
|
|
38
37
|
*/
|
|
39
|
-
export function tomorrow(
|
|
40
|
-
const targetDate = dayjs(
|
|
41
|
-
const component = new ParsingComponents(
|
|
38
|
+
export function tomorrow(reference: ReferenceWithTimezone): ParsingComponents {
|
|
39
|
+
const targetDate = dayjs(reference.instant);
|
|
40
|
+
const component = new ParsingComponents(reference, {});
|
|
42
41
|
assignTheNextDay(component, targetDate);
|
|
43
42
|
return component;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
export function tonight(
|
|
47
|
-
const targetDate = dayjs(
|
|
48
|
-
const component = new ParsingComponents(
|
|
45
|
+
export function tonight(reference: ReferenceWithTimezone, implyHour = 22): ParsingComponents {
|
|
46
|
+
const targetDate = dayjs(reference.instant);
|
|
47
|
+
const component = new ParsingComponents(reference, {});
|
|
49
48
|
component.imply("hour", implyHour);
|
|
50
49
|
component.imply("meridiem", Meridiem.PM);
|
|
51
50
|
assignSimilarDate(component, targetDate);
|
|
@@ -34,7 +34,7 @@ export default class ForwardDateRefiner implements Refiner {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
if (result.start.isOnlyWeekdayComponent() && refMoment.isAfter(result.start.dayjs())) {
|
|
37
|
-
if (refMoment.day()
|
|
37
|
+
if (refMoment.day() >= result.start.get("weekday")) {
|
|
38
38
|
refMoment = refMoment.day(result.start.get("weekday") + 7);
|
|
39
39
|
} else {
|
|
40
40
|
refMoment = refMoment.day(<number>result.start.get("weekday"));
|
package/src/index.ts
CHANGED
|
@@ -14,7 +14,7 @@ export interface ParsingOption {
|
|
|
14
14
|
/**
|
|
15
15
|
* Additional timezone keywords for the parsers to recognize
|
|
16
16
|
*/
|
|
17
|
-
timezones?: { string: number };
|
|
17
|
+
timezones?: { [tzKeyword: string]: number };
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Internal debug event handler.
|
|
@@ -23,6 +23,22 @@ export interface ParsingOption {
|
|
|
23
23
|
debug?: DebugHandler | DebugConsume;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
export interface ParsingReference {
|
|
27
|
+
/**
|
|
28
|
+
* Reference date. The instant (JavaScript Date object) when the input is written or mention.
|
|
29
|
+
* This effect date/time implication (e.g. weekday or time mentioning).
|
|
30
|
+
* (default = now)
|
|
31
|
+
*/
|
|
32
|
+
instant?: Date;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Reference timezone. The timezone where the input is written or mention.
|
|
36
|
+
* Date/time implication will account the difference between input timezone and the current system timezone.
|
|
37
|
+
* (default = current timezone)
|
|
38
|
+
*/
|
|
39
|
+
timezone?: string | number;
|
|
40
|
+
}
|
|
41
|
+
|
|
26
42
|
/**
|
|
27
43
|
* Parsed result or final output.
|
|
28
44
|
* Each result object represents a date/time (or date/time-range) mentioning in the input.
|
|
@@ -104,13 +120,13 @@ export const casual = en.casual;
|
|
|
104
120
|
/**
|
|
105
121
|
* A shortcut for {@link en | chrono.en.casual.parse()}
|
|
106
122
|
*/
|
|
107
|
-
export function parse(text: string, ref?: Date, option?: ParsingOption): ParsedResult[] {
|
|
123
|
+
export function parse(text: string, ref?: ParsingReference | Date, option?: ParsingOption): ParsedResult[] {
|
|
108
124
|
return casual.parse(text, ref, option);
|
|
109
125
|
}
|
|
110
126
|
|
|
111
127
|
/**
|
|
112
128
|
* A shortcut for {@link en | chrono.en.casual.parseDate()}
|
|
113
129
|
*/
|
|
114
|
-
export function parseDate(text: string, ref?: Date, option?: ParsingOption): Date {
|
|
130
|
+
export function parseDate(text: string, ref?: ParsingReference | Date, option?: ParsingOption): Date {
|
|
115
131
|
return casual.parseDate(text, ref, option);
|
|
116
132
|
}
|
|
@@ -108,7 +108,7 @@ export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType } = {
|
|
|
108
108
|
|
|
109
109
|
export const NUMBER_PATTERN = `(?:${matchAnyPattern(
|
|
110
110
|
INTEGER_WORD_DICTIONARY
|
|
111
|
-
)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an
|
|
111
|
+
)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an?\\b(?:\\s*few)?|few|several|a?\\s*couple\\s*(?:of)?)`;
|
|
112
112
|
|
|
113
113
|
export function parseNumberPattern(match: string): number {
|
|
114
114
|
const num = match.toLowerCase();
|
|
@@ -29,11 +29,11 @@ export default class DECasualDateParser extends AbstractParserWithWordBoundaryCh
|
|
|
29
29
|
let component = context.createParsingComponents();
|
|
30
30
|
switch (dateKeyword) {
|
|
31
31
|
case "jetzt":
|
|
32
|
-
component = references.now(context.
|
|
32
|
+
component = references.now(context.reference);
|
|
33
33
|
break;
|
|
34
34
|
|
|
35
35
|
case "heute":
|
|
36
|
-
component = references.today(context.
|
|
36
|
+
component = references.today(context.reference);
|
|
37
37
|
break;
|
|
38
38
|
|
|
39
39
|
case "morgen":
|
|
@@ -162,7 +162,7 @@ export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType } = {
|
|
|
162
162
|
|
|
163
163
|
export const NUMBER_PATTERN = `(?:${matchAnyPattern(
|
|
164
164
|
INTEGER_WORD_DICTIONARY
|
|
165
|
-
)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s
|
|
165
|
+
)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s{0,2}an?)?|an?\\b(?:\\s{0,2}few)?|few|several|a?\\s{0,2}couple\\s{0,2}(?:of)?)`;
|
|
166
166
|
|
|
167
167
|
export function parseNumberPattern(match: string): number {
|
|
168
168
|
const num = match.toLowerCase();
|
|
@@ -198,7 +198,7 @@ export function parseOrdinalNumberPattern(match: string): number {
|
|
|
198
198
|
|
|
199
199
|
//-----------------------------
|
|
200
200
|
|
|
201
|
-
export const YEAR_PATTERN = `(?:[1-9][0-9]{0,3}\\s
|
|
201
|
+
export const YEAR_PATTERN = `(?:[1-9][0-9]{0,3}\\s{0,2}(?:BE|AD|BC|BCE|CE)|[1-2][0-9]{3}|[5-9][0-9])`;
|
|
202
202
|
export function parseYear(match: string): number {
|
|
203
203
|
if (/BE/i.test(match)) {
|
|
204
204
|
// Buddhist Era
|
|
@@ -224,10 +224,10 @@ export function parseYear(match: string): number {
|
|
|
224
224
|
|
|
225
225
|
//-----------------------------
|
|
226
226
|
|
|
227
|
-
const SINGLE_TIME_UNIT_PATTERN = `(${NUMBER_PATTERN})\\s{0,
|
|
227
|
+
const SINGLE_TIME_UNIT_PATTERN = `(${NUMBER_PATTERN})\\s{0,3}(${matchAnyPattern(TIME_UNIT_DICTIONARY)})`;
|
|
228
228
|
const SINGLE_TIME_UNIT_REGEX = new RegExp(SINGLE_TIME_UNIT_PATTERN, "i");
|
|
229
229
|
|
|
230
|
-
export const TIME_UNITS_PATTERN = repeatedTimeunitPattern(`(?:(?:about|around)\\s
|
|
230
|
+
export const TIME_UNITS_PATTERN = repeatedTimeunitPattern(`(?:(?:about|around)\\s{0,3})?`, SINGLE_TIME_UNIT_PATTERN);
|
|
231
231
|
|
|
232
232
|
export function parseTimeUnits(timeunitText): TimeUnits {
|
|
233
233
|
const fragments = {};
|
|
@@ -235,7 +235,7 @@ export function parseTimeUnits(timeunitText): TimeUnits {
|
|
|
235
235
|
let match = SINGLE_TIME_UNIT_REGEX.exec(remainingText);
|
|
236
236
|
while (match) {
|
|
237
237
|
collectDateTimeFragment(fragments, match);
|
|
238
|
-
remainingText = remainingText.substring(match[0].length);
|
|
238
|
+
remainingText = remainingText.substring(match[0].length).trim();
|
|
239
239
|
match = SINGLE_TIME_UNIT_REGEX.exec(remainingText);
|
|
240
240
|
}
|
|
241
241
|
return fragments;
|
|
@@ -19,21 +19,21 @@ export default class ENCasualDateParser extends AbstractParserWithWordBoundaryCh
|
|
|
19
19
|
|
|
20
20
|
switch (lowerText) {
|
|
21
21
|
case "now":
|
|
22
|
-
return references.now(context.
|
|
22
|
+
return references.now(context.reference);
|
|
23
23
|
|
|
24
24
|
case "today":
|
|
25
|
-
return references.today(context.
|
|
25
|
+
return references.today(context.reference);
|
|
26
26
|
|
|
27
27
|
case "yesterday":
|
|
28
|
-
return references.yesterday(context.
|
|
28
|
+
return references.yesterday(context.reference);
|
|
29
29
|
|
|
30
30
|
case "tomorrow":
|
|
31
31
|
case "tmr":
|
|
32
32
|
case "tmrw":
|
|
33
|
-
return references.tomorrow(context.
|
|
33
|
+
return references.tomorrow(context.reference);
|
|
34
34
|
|
|
35
35
|
case "tonight":
|
|
36
|
-
return references.tonight(context.
|
|
36
|
+
return references.tonight(context.reference);
|
|
37
37
|
|
|
38
38
|
default:
|
|
39
39
|
if (lowerText.match(/last\s*night/)) {
|
|
@@ -4,7 +4,7 @@ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/
|
|
|
4
4
|
import dayjs from "dayjs";
|
|
5
5
|
import { assignTheNextDay } from "../../../utils/dayjs";
|
|
6
6
|
|
|
7
|
-
const PATTERN = /(?:this)?\s
|
|
7
|
+
const PATTERN = /(?:this)?\s{0,3}(morning|afternoon|evening|night|midnight|noon)(?=\W|$)/i;
|
|
8
8
|
|
|
9
9
|
export default class ENCasualTimeParser extends AbstractParserWithWordBoundaryChecking {
|
|
10
10
|
innerPattern() {
|
|
@@ -7,20 +7,19 @@ import { ORDINAL_NUMBER_PATTERN, parseOrdinalNumberPattern } from "../constants"
|
|
|
7
7
|
import { matchAnyPattern } from "../../../utils/pattern";
|
|
8
8
|
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
|
|
9
9
|
|
|
10
|
+
// prettier-ignore
|
|
10
11
|
const PATTERN = new RegExp(
|
|
11
|
-
|
|
12
|
-
`(${ORDINAL_NUMBER_PATTERN})` +
|
|
13
|
-
"(?:\\s*" +
|
|
14
|
-
"(?:to|\\-|\\–|until|through|till|\\s)\\s*" +
|
|
12
|
+
`(?:on\\s{0,3})?` +
|
|
15
13
|
`(${ORDINAL_NUMBER_PATTERN})` +
|
|
14
|
+
`(?:` +
|
|
15
|
+
`\\s{0,3}(?:to|\\-|\\–|until|through|till)?\\s{0,3}` +
|
|
16
|
+
`(${ORDINAL_NUMBER_PATTERN})` +
|
|
16
17
|
")?" +
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
matchAnyPattern(MONTH_DICTIONARY) +
|
|
20
|
-
")" +
|
|
18
|
+
`(?:-|/|\\s{0,3}(?:of)?\\s{0,3})` +
|
|
19
|
+
`(${matchAnyPattern(MONTH_DICTIONARY)})` +
|
|
21
20
|
"(?:" +
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
`(?:-|/|,?\\s{0,3})` +
|
|
22
|
+
`(${YEAR_PATTERN}(?![^\\s]\\d))` +
|
|
24
23
|
")?" +
|
|
25
24
|
"(?=\\W|$)",
|
|
26
25
|
"i"
|
|
@@ -26,17 +26,17 @@ export default class ENRelativeDateFormatParser extends AbstractParserWithWordBo
|
|
|
26
26
|
if (modifier == "next") {
|
|
27
27
|
const timeUnits = {};
|
|
28
28
|
timeUnits[timeunit] = 1;
|
|
29
|
-
return ParsingComponents.
|
|
29
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if (modifier == "last" || modifier == "past") {
|
|
33
33
|
const timeUnits = {};
|
|
34
34
|
timeUnits[timeunit] = -1;
|
|
35
|
-
return ParsingComponents.
|
|
35
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const components = context.createParsingComponents();
|
|
39
|
-
let date = dayjs(context.
|
|
39
|
+
let date = dayjs(context.reference.instant);
|
|
40
40
|
|
|
41
41
|
// This week
|
|
42
42
|
if (unitWord.match(/week/i)) {
|
|
@@ -4,9 +4,8 @@ import { ParsingComponents } from "../../../results";
|
|
|
4
4
|
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
|
|
5
5
|
import { reverseTimeUnits } from "../../../utils/timeunits";
|
|
6
6
|
|
|
7
|
-
const PATTERN = new RegExp(
|
|
8
|
-
|
|
9
|
-
const STRICT_PATTERN = new RegExp("" + "(" + TIME_UNITS_PATTERN + ")" + "ago(?=(?:\\W|$))", "i");
|
|
7
|
+
const PATTERN = new RegExp(`(${TIME_UNITS_PATTERN})\\s{0,5}(?:ago|before|earlier)(?=(?:\\W|$))`, "i");
|
|
8
|
+
const STRICT_PATTERN = new RegExp(`(${TIME_UNITS_PATTERN})\\s{0,5}ago(?=(?:\\W|$))`, "i");
|
|
10
9
|
|
|
11
10
|
export default class ENTimeUnitAgoFormatParser extends AbstractParserWithWordBoundaryChecking {
|
|
12
11
|
constructor(private strictMode: boolean) {
|
|
@@ -21,6 +20,6 @@ export default class ENTimeUnitAgoFormatParser extends AbstractParserWithWordBou
|
|
|
21
20
|
const timeUnits = parseTimeUnits(match[1]);
|
|
22
21
|
const outputTimeUnits = reverseTimeUnits(timeUnits);
|
|
23
22
|
|
|
24
|
-
return ParsingComponents.
|
|
23
|
+
return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
|
|
25
24
|
}
|
|
26
25
|
}
|
|
@@ -22,6 +22,6 @@ export default class ENTimeUnitCasualRelativeFormatParser extends AbstractParser
|
|
|
22
22
|
break;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
return ParsingComponents.
|
|
25
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -4,7 +4,7 @@ import { ParsingComponents } from "../../../results";
|
|
|
4
4
|
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
|
|
5
5
|
|
|
6
6
|
const PATTERN = new RegExp(
|
|
7
|
-
|
|
7
|
+
`(${TIME_UNITS_PATTERN})\\s{0,5}(?:later|after|from now|henceforth|forward|out)` + "(?=(?:\\W|$))",
|
|
8
8
|
"i"
|
|
9
9
|
);
|
|
10
10
|
|
|
@@ -22,6 +22,6 @@ export default class ENTimeUnitLaterFormatParser extends AbstractParserWithWordB
|
|
|
22
22
|
|
|
23
23
|
innerExtract(context: ParsingContext, match: RegExpMatchArray) {
|
|
24
24
|
const fragments = parseTimeUnits(match[GROUP_NUM_TIMEUNITS]);
|
|
25
|
-
return ParsingComponents.
|
|
25
|
+
return ParsingComponents.createRelativeFromReference(context.reference, fragments);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -21,6 +21,6 @@ export default class ENTimeUnitWithinFormatParser extends AbstractParserWithWord
|
|
|
21
21
|
|
|
22
22
|
innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
|
|
23
23
|
const timeUnits = parseTimeUnits(match[1]);
|
|
24
|
-
return ParsingComponents.
|
|
24
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -105,7 +105,7 @@ export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType | QUnitType } =
|
|
|
105
105
|
|
|
106
106
|
export const NUMBER_PATTERN = `(?:${matchAnyPattern(
|
|
107
107
|
INTEGER_WORD_DICTIONARY
|
|
108
|
-
)}|[0-9]+|[0-9]+\\.[0-9]+|une
|
|
108
|
+
)}|[0-9]+|[0-9]+\\.[0-9]+|une?\\b|quelques?|demi-?)`;
|
|
109
109
|
|
|
110
110
|
export function parseNumberPattern(match: string): number {
|
|
111
111
|
const num = match.toLowerCase();
|
|
@@ -18,16 +18,16 @@ export default class FRCasualDateParser extends AbstractParserWithWordBoundaryCh
|
|
|
18
18
|
|
|
19
19
|
switch (lowerText) {
|
|
20
20
|
case "maintenant":
|
|
21
|
-
return references.now(context.
|
|
21
|
+
return references.now(context.reference);
|
|
22
22
|
|
|
23
23
|
case "aujourd'hui":
|
|
24
|
-
return references.today(context.
|
|
24
|
+
return references.today(context.reference);
|
|
25
25
|
|
|
26
26
|
case "hier":
|
|
27
|
-
return references.yesterday(context.
|
|
27
|
+
return references.yesterday(context.reference);
|
|
28
28
|
|
|
29
29
|
case "demain":
|
|
30
|
-
return references.tomorrow(context.
|
|
30
|
+
return references.tomorrow(context.reference);
|
|
31
31
|
|
|
32
32
|
default:
|
|
33
33
|
if (lowerText.match(/cette\s*nuit/)) {
|
|
@@ -17,6 +17,6 @@ export default class FRTimeUnitAgoFormatParser extends AbstractParserWithWordBou
|
|
|
17
17
|
const timeUnits = parseTimeUnits(match[1]);
|
|
18
18
|
const outputTimeUnits = reverseTimeUnits(timeUnits);
|
|
19
19
|
|
|
20
|
-
return ParsingComponents.
|
|
20
|
+
return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -38,6 +38,6 @@ export default class FRTimeUnitAgoFormatParser extends AbstractParserWithWordBou
|
|
|
38
38
|
timeUnits = reverseTimeUnits(timeUnits);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
return ParsingComponents.
|
|
41
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -10,6 +10,6 @@ export default class FRTimeUnitWithinFormatParser extends AbstractParserWithWord
|
|
|
10
10
|
|
|
11
11
|
innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
|
|
12
12
|
const timeUnits = parseTimeUnits(match[1]);
|
|
13
|
-
return ParsingComponents.
|
|
13
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -18,14 +18,14 @@ export default class JPCasualDateParser implements Parser {
|
|
|
18
18
|
|
|
19
19
|
switch (text) {
|
|
20
20
|
case "昨日":
|
|
21
|
-
return references.yesterday(context.
|
|
21
|
+
return references.yesterday(context.reference);
|
|
22
22
|
|
|
23
23
|
case "明日":
|
|
24
|
-
return references.tomorrow(context.
|
|
24
|
+
return references.tomorrow(context.reference);
|
|
25
25
|
|
|
26
26
|
case "今日":
|
|
27
27
|
case "当日":
|
|
28
|
-
return references.today(context.
|
|
28
|
+
return references.today(context.reference);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
if (text == "今夜" || text == "今夕" || text == "今晩") {
|
|
@@ -141,11 +141,14 @@ export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType } = {
|
|
|
141
141
|
min: "minute",
|
|
142
142
|
mins: "minute",
|
|
143
143
|
minute: "minute",
|
|
144
|
+
minuut: "minute",
|
|
144
145
|
minuten: "minute",
|
|
146
|
+
minuutje: "minute",
|
|
145
147
|
h: "hour",
|
|
146
148
|
hr: "hour",
|
|
147
149
|
hrs: "hour",
|
|
148
150
|
uur: "hour",
|
|
151
|
+
u: "hour",
|
|
149
152
|
uren: "hour",
|
|
150
153
|
dag: "d",
|
|
151
154
|
dagen: "d",
|
|
@@ -160,18 +163,21 @@ export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType } = {
|
|
|
160
163
|
|
|
161
164
|
//-----------------------------
|
|
162
165
|
|
|
163
|
-
export const NUMBER_PATTERN = `(?:${matchAnyPattern(
|
|
166
|
+
export const NUMBER_PATTERN = `(?:${matchAnyPattern(
|
|
167
|
+
INTEGER_WORD_DICTIONARY
|
|
168
|
+
)}|[0-9]+|[0-9]+[\\.,][0-9]+|halve?|half|paar)`;
|
|
164
169
|
|
|
165
170
|
export function parseNumberPattern(match: string): number {
|
|
166
171
|
const num = match.toLowerCase();
|
|
167
172
|
if (INTEGER_WORD_DICTIONARY[num] !== undefined) {
|
|
168
173
|
return INTEGER_WORD_DICTIONARY[num];
|
|
169
|
-
} else if (num === "
|
|
170
|
-
return
|
|
171
|
-
} else if (num.match(/halve?/)) {
|
|
174
|
+
} else if (num === "paar") {
|
|
175
|
+
return 2;
|
|
176
|
+
} else if (num === "half" || num.match(/halve?/)) {
|
|
172
177
|
return 0.5;
|
|
173
178
|
}
|
|
174
|
-
|
|
179
|
+
// Replace "," with "." to support some European languages
|
|
180
|
+
return parseFloat(num.replace(",", "."));
|
|
175
181
|
}
|
|
176
182
|
|
|
177
183
|
//-----------------------------
|
package/src/locales/nl/index.ts
CHANGED
|
@@ -20,6 +20,10 @@ import NLSlashMonthFormatParser from "./parsers/NLSlashMonthFormatParser";
|
|
|
20
20
|
import NLTimeExpressionParser from "./parsers/NLTimeExpressionParser";
|
|
21
21
|
import NLCasualYearMonthDayParser from "./parsers/NLCasualYearMonthDayParser";
|
|
22
22
|
import NLCasualDateTimeParser from "./parsers/NLCasualDateTimeParser";
|
|
23
|
+
import NLTimeUnitCasualRelativeFormatParser from "./parsers/NLTimeUnitCasualRelativeFormatParser";
|
|
24
|
+
import NLRelativeDateFormatParser from "./parsers/NLRelativeDateFormatParser";
|
|
25
|
+
import NLTimeUnitAgoFormatParser from "./parsers/NLTimeUnitAgoFormatParser";
|
|
26
|
+
import NLTimeUnitLaterFormatParser from "./parsers/NLTimeUnitLaterFormatParser";
|
|
23
27
|
|
|
24
28
|
// Shortcuts
|
|
25
29
|
export const casual = new Chrono(createCasualConfiguration());
|
|
@@ -38,6 +42,9 @@ export function createCasualConfiguration(littleEndian = true): Configuration {
|
|
|
38
42
|
option.parsers.unshift(new NLCasualDateParser());
|
|
39
43
|
option.parsers.unshift(new NLCasualTimeParser());
|
|
40
44
|
option.parsers.unshift(new NLCasualDateTimeParser());
|
|
45
|
+
option.parsers.unshift(new NLMonthNameParser());
|
|
46
|
+
option.parsers.unshift(new NLRelativeDateFormatParser());
|
|
47
|
+
option.parsers.unshift(new NLTimeUnitCasualRelativeFormatParser());
|
|
41
48
|
return option;
|
|
42
49
|
}
|
|
43
50
|
|
|
@@ -49,13 +56,15 @@ export function createConfiguration(strictMode = true, littleEndian = true): Con
|
|
|
49
56
|
{
|
|
50
57
|
parsers: [
|
|
51
58
|
new SlashDateFormatParser(littleEndian),
|
|
59
|
+
new NLTimeUnitWithinFormatParser(),
|
|
52
60
|
new NLMonthNameMiddleEndianParser(),
|
|
53
61
|
new NLMonthNameParser(),
|
|
54
|
-
new NLTimeExpressionParser(),
|
|
55
|
-
new NLTimeUnitWithinFormatParser(),
|
|
56
|
-
new NLSlashMonthFormatParser(),
|
|
57
62
|
new NLWeekdayParser(),
|
|
58
63
|
new NLCasualYearMonthDayParser(),
|
|
64
|
+
new NLSlashMonthFormatParser(),
|
|
65
|
+
new NLTimeExpressionParser(strictMode),
|
|
66
|
+
new NLTimeUnitAgoFormatParser(strictMode),
|
|
67
|
+
new NLTimeUnitLaterFormatParser(strictMode),
|
|
59
68
|
],
|
|
60
69
|
refiners: [new NLMergeDateTimeRefiner(), new NLMergeDateRangeRefiner()],
|
|
61
70
|
},
|
|
@@ -14,17 +14,17 @@ export default class NLCasualDateParser extends AbstractParserWithWordBoundaryCh
|
|
|
14
14
|
|
|
15
15
|
switch (lowerText) {
|
|
16
16
|
case "nu":
|
|
17
|
-
return references.now(context.
|
|
17
|
+
return references.now(context.reference);
|
|
18
18
|
|
|
19
19
|
case "vandaag":
|
|
20
|
-
return references.today(context.
|
|
20
|
+
return references.today(context.reference);
|
|
21
21
|
|
|
22
22
|
case "morgen":
|
|
23
23
|
case "morgend":
|
|
24
|
-
return references.tomorrow(context.
|
|
24
|
+
return references.tomorrow(context.reference);
|
|
25
25
|
|
|
26
26
|
case "gisteren":
|
|
27
|
-
return references.yesterday(context.
|
|
27
|
+
return references.yesterday(context.reference);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
return component;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { TIME_UNIT_DICTIONARY } from "../constants";
|
|
2
|
+
import { ParsingContext } from "../../../chrono";
|
|
3
|
+
import { ParsingComponents } from "../../../results";
|
|
4
|
+
import dayjs from "dayjs";
|
|
5
|
+
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
|
|
6
|
+
import { matchAnyPattern } from "../../../utils/pattern";
|
|
7
|
+
|
|
8
|
+
const PATTERN = new RegExp(
|
|
9
|
+
`(dit|deze|komende|volgend|volgende|afgelopen|vorige)\\s*(${matchAnyPattern(TIME_UNIT_DICTIONARY)})(?=\\s*)` +
|
|
10
|
+
"(?=\\W|$)",
|
|
11
|
+
"i"
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const MODIFIER_WORD_GROUP = 1;
|
|
15
|
+
const RELATIVE_WORD_GROUP = 2;
|
|
16
|
+
|
|
17
|
+
export default class NLRelativeDateFormatParser extends AbstractParserWithWordBoundaryChecking {
|
|
18
|
+
innerPattern(): RegExp {
|
|
19
|
+
return PATTERN;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
|
|
23
|
+
const modifier = match[MODIFIER_WORD_GROUP].toLowerCase();
|
|
24
|
+
const unitWord = match[RELATIVE_WORD_GROUP].toLowerCase();
|
|
25
|
+
const timeunit = TIME_UNIT_DICTIONARY[unitWord];
|
|
26
|
+
|
|
27
|
+
if (modifier == "volgend" || modifier == "volgende" || modifier == "komende") {
|
|
28
|
+
const timeUnits = {};
|
|
29
|
+
timeUnits[timeunit] = 1;
|
|
30
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (modifier == "afgelopen" || modifier == "vorige") {
|
|
34
|
+
const timeUnits = {};
|
|
35
|
+
timeUnits[timeunit] = -1;
|
|
36
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const components = context.createParsingComponents();
|
|
40
|
+
let date = dayjs(context.reference.instant);
|
|
41
|
+
|
|
42
|
+
// This week
|
|
43
|
+
if (unitWord.match(/week/i)) {
|
|
44
|
+
date = date.add(-date.get("d"), "d");
|
|
45
|
+
components.imply("day", date.date());
|
|
46
|
+
components.imply("month", date.month() + 1);
|
|
47
|
+
components.imply("year", date.year());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// This month
|
|
51
|
+
else if (unitWord.match(/maand/i)) {
|
|
52
|
+
date = date.add(-date.date() + 1, "d");
|
|
53
|
+
components.imply("day", date.date());
|
|
54
|
+
components.assign("year", date.year());
|
|
55
|
+
components.assign("month", date.month() + 1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// This year
|
|
59
|
+
else if (unitWord.match(/jaar/i)) {
|
|
60
|
+
date = date.add(-date.date() + 1, "d");
|
|
61
|
+
date = date.add(-date.month(), "month");
|
|
62
|
+
|
|
63
|
+
components.imply("day", date.date());
|
|
64
|
+
components.imply("month", date.month() + 1);
|
|
65
|
+
components.assign("year", date.year());
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return components;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -11,6 +11,10 @@ export default class NLTimeExpressionParser extends AbstractTimeExpressionParser
|
|
|
11
11
|
return "\\s*(?:\\-|\\–|\\~|\\〜|om|\\?)\\s*";
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
primarySuffix(): string {
|
|
15
|
+
return "(?:\\s*(?:uur))?(?!/)(?=\\W|$)";
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
extractPrimaryTimeComponents(context: ParsingContext, match: RegExpMatchArray): ParsingComponents | null {
|
|
15
19
|
// This looks more like a year e.g. 2020
|
|
16
20
|
if (match[0].match(/^\s*\d{4}\s*$/)) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ParsingContext } from "../../../chrono";
|
|
2
|
+
import { parseTimeUnits, TIME_UNITS_PATTERN } from "../constants";
|
|
3
|
+
import { ParsingComponents } from "../../../results";
|
|
4
|
+
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
|
|
5
|
+
import { reverseTimeUnits } from "../../../utils/timeunits";
|
|
6
|
+
|
|
7
|
+
const PATTERN = new RegExp("" + "(" + TIME_UNITS_PATTERN + ")" + "(?:geleden|voor|eerder)(?=(?:\\W|$))", "i");
|
|
8
|
+
|
|
9
|
+
const STRICT_PATTERN = new RegExp("" + "(" + TIME_UNITS_PATTERN + ")" + "geleden(?=(?:\\W|$))", "i");
|
|
10
|
+
|
|
11
|
+
export default class NLTimeUnitAgoFormatParser extends AbstractParserWithWordBoundaryChecking {
|
|
12
|
+
constructor(private strictMode: boolean) {
|
|
13
|
+
super();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
innerPattern(): RegExp {
|
|
17
|
+
return this.strictMode ? STRICT_PATTERN : PATTERN;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
innerExtract(context: ParsingContext, match: RegExpMatchArray) {
|
|
21
|
+
const timeUnits = parseTimeUnits(match[1]);
|
|
22
|
+
const outputTimeUnits = reverseTimeUnits(timeUnits);
|
|
23
|
+
|
|
24
|
+
return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
|
|
25
|
+
}
|
|
26
|
+
}
|