chrono-node 2.3.1 → 2.3.5
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 +1 -1
- package/dist/common/casualReferences.js +3 -1
- package/dist/common/parsers/AbstractParserWithWordBoundary.js +2 -1
- package/dist/common/refiners/ForwardDateRefiner.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/locales/de/constants.js +1 -1
- package/dist/locales/en/constants.js +1 -1
- package/dist/locales/en/parsers/ENRelativeDateFormatParser.js +3 -3
- package/dist/locales/en/parsers/ENTimeUnitAgoFormatParser.js +1 -1
- package/dist/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.js +1 -1
- package/dist/locales/en/parsers/ENTimeUnitLaterFormatParser.js +1 -1
- package/dist/locales/en/parsers/ENTimeUnitWithinFormatParser.js +1 -1
- package/dist/locales/fr/constants.js +1 -1
- 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/nl/parsers/NLRelativeDateFormatParser.js +3 -3
- package/dist/locales/nl/parsers/NLTimeUnitAgoFormatParser.js +1 -1
- package/dist/locales/nl/parsers/NLTimeUnitCasualRelativeFormatParser.js +1 -1
- package/dist/locales/nl/parsers/NLTimeUnitLaterFormatParser.js +1 -1
- package/dist/locales/nl/parsers/NLTimeUnitWithinFormatParser.js +1 -1
- package/dist/locales/zh/hant/constants.d.ts +28 -0
- package/dist/locales/zh/hant/constants.js +52 -0
- package/dist/locales/zh/hant/parsers/ZHHantCasualDateParser.d.ts +7 -0
- package/dist/locales/zh/hant/parsers/ZHHantCasualDateParser.js +138 -0
- package/dist/locales/zh/hant/parsers/ZHHantDateParser.d.ts +6 -0
- package/dist/locales/zh/hant/parsers/ZHHantDateParser.js +64 -0
- package/dist/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.d.ts +6 -0
- package/dist/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.js +78 -0
- package/dist/locales/zh/hant/parsers/ZHHantRelationWeekdayParser.d.ts +7 -0
- package/dist/locales/zh/hant/parsers/ZHHantRelationWeekdayParser.js +70 -0
- package/dist/locales/zh/hant/parsers/ZHHantTimeExpressionParser.d.ts +6 -0
- package/dist/locales/zh/hant/parsers/ZHHantTimeExpressionParser.js +438 -0
- package/dist/locales/zh/hant/parsers/ZHHantWeekdayParser.d.ts +7 -0
- package/dist/locales/zh/hant/parsers/ZHHantWeekdayParser.js +46 -0
- package/dist/locales/zh/hant/refiners/ZHHantMergeDateRangeRefiner.d.ts +4 -0
- package/dist/locales/zh/hant/refiners/ZHHantMergeDateRangeRefiner.js +12 -0
- package/dist/locales/zh/hant/refiners/ZHHantMergeDateTimeRefiner.d.ts +4 -0
- package/dist/locales/zh/hant/refiners/ZHHantMergeDateTimeRefiner.js +12 -0
- package/dist/locales/zh/index.d.ts +9 -0
- package/dist/locales/zh/index.js +49 -0
- package/dist/results.d.ts +2 -2
- package/dist/results.js +18 -12
- package/dist/timezone.d.ts +1 -1
- package/dist/timezone.js +3 -0
- package/dist/utils/dayjs.js +7 -0
- package/package.json +1 -1
- package/src/common/casualReferences.ts +3 -1
- package/src/common/parsers/AbstractParserWithWordBoundary.ts +1 -1
- package/src/common/refiners/ForwardDateRefiner.ts +1 -1
- package/src/index.ts +2 -1
- package/src/locales/de/constants.ts +1 -1
- package/src/locales/en/constants.ts +1 -1
- package/src/locales/en/parsers/ENRelativeDateFormatParser.ts +3 -3
- package/src/locales/en/parsers/ENTimeUnitAgoFormatParser.ts +1 -1
- package/src/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.ts +1 -1
- package/src/locales/en/parsers/ENTimeUnitLaterFormatParser.ts +1 -1
- package/src/locales/en/parsers/ENTimeUnitWithinFormatParser.ts +1 -1
- package/src/locales/fr/constants.ts +1 -1
- 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/nl/parsers/NLRelativeDateFormatParser.ts +3 -3
- package/src/locales/nl/parsers/NLTimeUnitAgoFormatParser.ts +1 -1
- package/src/locales/nl/parsers/NLTimeUnitCasualRelativeFormatParser.ts +1 -1
- package/src/locales/nl/parsers/NLTimeUnitLaterFormatParser.ts +1 -1
- package/src/locales/nl/parsers/NLTimeUnitWithinFormatParser.ts +1 -1
- package/src/locales/zh/hant/constants.ts +53 -0
- package/src/locales/zh/hant/parsers/ZHHantCasualDateParser.ts +128 -0
- package/src/locales/zh/hant/parsers/ZHHantDateParser.ts +68 -0
- package/src/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.ts +81 -0
- package/src/locales/zh/hant/parsers/ZHHantRelationWeekdayParser.ts +69 -0
- package/src/locales/zh/hant/parsers/ZHHantTimeExpressionParser.ts +424 -0
- package/src/locales/zh/hant/parsers/ZHHantWeekdayParser.ts +46 -0
- package/src/locales/zh/hant/refiners/ZHHantMergeDateRangeRefiner.ts +7 -0
- package/src/locales/zh/hant/refiners/ZHHantMergeDateTimeRefiner.ts +7 -0
- package/src/locales/zh/index.ts +63 -0
- package/src/results.ts +22 -12
- package/src/timezone.ts +5 -1
- package/src/utils/dayjs.ts +6 -0
- package/test/en/en_casual.test.ts +11 -0
- package/test/en/en_month_name_little_endian.test.ts +10 -0
- package/test/en/en_relative.test.ts +8 -0
- package/test/en/en_slash.test.ts +11 -0
- package/test/en/en_time_units_ago.test.ts +16 -0
- package/test/en/en_time_units_later.test.ts +6 -0
- package/test/en/en_timezone_exp.test.ts +85 -10
- package/test/en/en_weekday.test.ts +69 -25
- package/test/en/negative_cases.test.ts +2 -0
- package/test/test_util.ts +5 -2
- package/test/zh/zh.test.ts +18 -0
- package/test/zh/zh_hant_casual.test.ts +246 -0
- package/test/zh/zh_hant_date.test.ts +103 -0
- package/test/zh/zh_hant_deadline.test.ts +136 -0
- package/test/zh/zh_hant_time_exp.test.ts +182 -0
- package/test/zh/zh_hant_weekday.test.ts +132 -0
package/dist/results.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Component, ParsedComponents, ParsedResult, ParsingReference } from "./i
|
|
|
2
2
|
import dayjs, { OpUnitType, QUnitType } from "dayjs";
|
|
3
3
|
export declare class ReferenceWithTimezone {
|
|
4
4
|
readonly instant: Date;
|
|
5
|
-
readonly timezoneOffset
|
|
5
|
+
readonly timezoneOffset?: number;
|
|
6
6
|
constructor(input?: ParsingReference | Date);
|
|
7
7
|
}
|
|
8
8
|
export declare class ParsingComponents implements ParsedComponents {
|
|
@@ -29,7 +29,7 @@ export declare class ParsingComponents implements ParsedComponents {
|
|
|
29
29
|
date(): Date;
|
|
30
30
|
private dateWithoutTimezoneAdjustment;
|
|
31
31
|
private getSystemTimezoneAdjustmentMinute;
|
|
32
|
-
static
|
|
32
|
+
static createRelativeFromReference(reference: ReferenceWithTimezone, fragments: {
|
|
33
33
|
[c in OpUnitType | QUnitType]?: number;
|
|
34
34
|
}): ParsingComponents;
|
|
35
35
|
}
|
package/dist/results.js
CHANGED
|
@@ -11,7 +11,7 @@ const timezone_1 = require("./timezone");
|
|
|
11
11
|
dayjs_1.default.extend(quarterOfYear_1.default);
|
|
12
12
|
class ReferenceWithTimezone {
|
|
13
13
|
constructor(input) {
|
|
14
|
-
var _a
|
|
14
|
+
var _a;
|
|
15
15
|
input = input !== null && input !== void 0 ? input : new Date();
|
|
16
16
|
if (input instanceof Date) {
|
|
17
17
|
this.instant = input;
|
|
@@ -19,7 +19,7 @@ class ReferenceWithTimezone {
|
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
21
21
|
this.instant = (_a = input.instant) !== null && _a !== void 0 ? _a : new Date();
|
|
22
|
-
this.timezoneOffset = timezone_1.toTimezoneOffset(
|
|
22
|
+
this.timezoneOffset = timezone_1.toTimezoneOffset(input.timezone);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -120,34 +120,40 @@ class ParsingComponents {
|
|
|
120
120
|
}
|
|
121
121
|
date() {
|
|
122
122
|
const date = this.dateWithoutTimezoneAdjustment();
|
|
123
|
-
return new Date(date.getTime() + this.getSystemTimezoneAdjustmentMinute() * 60000);
|
|
123
|
+
return new Date(date.getTime() + this.getSystemTimezoneAdjustmentMinute(date) * 60000);
|
|
124
124
|
}
|
|
125
125
|
dateWithoutTimezoneAdjustment() {
|
|
126
126
|
const date = new Date(this.get("year"), this.get("month") - 1, this.get("day"), this.get("hour"), this.get("minute"), this.get("second"), this.get("millisecond"));
|
|
127
127
|
date.setFullYear(this.get("year"));
|
|
128
128
|
return date;
|
|
129
129
|
}
|
|
130
|
-
getSystemTimezoneAdjustmentMinute() {
|
|
131
|
-
var _a;
|
|
132
|
-
|
|
133
|
-
|
|
130
|
+
getSystemTimezoneAdjustmentMinute(date) {
|
|
131
|
+
var _a, _b;
|
|
132
|
+
if (!date || date.getTime() < 0) {
|
|
133
|
+
date = new Date();
|
|
134
|
+
}
|
|
135
|
+
const currentTimezoneOffset = -date.getTimezoneOffset();
|
|
136
|
+
const targetTimezoneOffset = (_b = (_a = this.get("timezoneOffset")) !== null && _a !== void 0 ? _a : this.reference.timezoneOffset) !== null && _b !== void 0 ? _b : currentTimezoneOffset;
|
|
134
137
|
return currentTimezoneOffset - targetTimezoneOffset;
|
|
135
138
|
}
|
|
136
|
-
static
|
|
137
|
-
let date = dayjs_1.default(
|
|
139
|
+
static createRelativeFromReference(reference, fragments) {
|
|
140
|
+
let date = dayjs_1.default(reference.instant);
|
|
138
141
|
for (const key in fragments) {
|
|
139
142
|
date = date.add(fragments[key], key);
|
|
140
143
|
}
|
|
141
|
-
const reference = new ReferenceWithTimezone(refInstant);
|
|
142
144
|
const components = new ParsingComponents(reference);
|
|
143
145
|
if (fragments["hour"] || fragments["minute"] || fragments["second"]) {
|
|
144
146
|
dayjs_2.assignSimilarTime(components, date);
|
|
145
147
|
dayjs_2.assignSimilarDate(components, date);
|
|
146
|
-
|
|
148
|
+
if (reference.timezoneOffset !== null) {
|
|
149
|
+
components.assign("timezoneOffset", -reference.instant.getTimezoneOffset());
|
|
150
|
+
}
|
|
147
151
|
}
|
|
148
152
|
else {
|
|
149
153
|
dayjs_2.implySimilarTime(components, date);
|
|
150
|
-
|
|
154
|
+
if (reference.timezoneOffset !== null) {
|
|
155
|
+
components.imply("timezoneOffset", -reference.instant.getTimezoneOffset());
|
|
156
|
+
}
|
|
151
157
|
if (fragments["d"]) {
|
|
152
158
|
components.assign("day", date.date());
|
|
153
159
|
components.assign("month", date.month() + 1);
|
package/dist/timezone.d.ts
CHANGED
|
@@ -191,4 +191,4 @@ export declare const TIMEZONE_ABBR_MAP: {
|
|
|
191
191
|
YEKST: number;
|
|
192
192
|
YEKT: number;
|
|
193
193
|
};
|
|
194
|
-
export declare function toTimezoneOffset(timezoneInput: string | number): number;
|
|
194
|
+
export declare function toTimezoneOffset(timezoneInput: string | number): number | null;
|
package/dist/timezone.js
CHANGED
package/dist/utils/dayjs.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.implySimilarTime = exports.assignSimilarTime = exports.assignSimilarDate = exports.assignTheNextDay = void 0;
|
|
4
|
+
const index_1 = require("../index");
|
|
4
5
|
function assignTheNextDay(component, targetDayJs) {
|
|
5
6
|
targetDayJs = targetDayJs.add(1, "day");
|
|
6
7
|
assignSimilarDate(component, targetDayJs);
|
|
@@ -18,6 +19,12 @@ function assignSimilarTime(component, targetDayJs) {
|
|
|
18
19
|
component.assign("minute", targetDayJs.minute());
|
|
19
20
|
component.assign("second", targetDayJs.second());
|
|
20
21
|
component.assign("millisecond", targetDayJs.millisecond());
|
|
22
|
+
if (component.get("hour") < 12) {
|
|
23
|
+
component.assign("meridiem", index_1.Meridiem.AM);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
component.assign("meridiem", index_1.Meridiem.PM);
|
|
27
|
+
}
|
|
21
28
|
}
|
|
22
29
|
exports.assignSimilarTime = assignSimilarTime;
|
|
23
30
|
function implySimilarTime(component, targetDayJs) {
|
package/package.json
CHANGED
|
@@ -8,7 +8,9 @@ export function now(reference: ReferenceWithTimezone): ParsingComponents {
|
|
|
8
8
|
const component = new ParsingComponents(reference, {});
|
|
9
9
|
assignSimilarDate(component, targetDate);
|
|
10
10
|
assignSimilarTime(component, targetDate);
|
|
11
|
-
|
|
11
|
+
if (reference.timezoneOffset !== null) {
|
|
12
|
+
component.assign("timezoneOffset", targetDate.utcOffset());
|
|
13
|
+
}
|
|
12
14
|
return component;
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -27,7 +27,7 @@ export abstract class AbstractParserWithWordBoundaryChecking implements Parser {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
extract(context: ParsingContext, match: RegExpMatchArray) {
|
|
30
|
-
const header = match[1];
|
|
30
|
+
const header = match[1] ?? "";
|
|
31
31
|
match.index = match.index + header.length;
|
|
32
32
|
match[0] = match[0].substring(header.length);
|
|
33
33
|
for (let i = 2; i < match.length; i++) {
|
|
@@ -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
|
@@ -105,7 +105,8 @@ import * as fr from "./locales/fr";
|
|
|
105
105
|
import * as ja from "./locales/ja";
|
|
106
106
|
import * as pt from "./locales/pt";
|
|
107
107
|
import * as nl from "./locales/nl";
|
|
108
|
-
|
|
108
|
+
import * as zh from "./locales/zh";
|
|
109
|
+
export { de, fr, ja, pt, nl, zh };
|
|
109
110
|
|
|
110
111
|
/**
|
|
111
112
|
* A shortcut for {@link en | chrono.en.strict}
|
|
@@ -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();
|
|
@@ -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{0,2}an?)?|an
|
|
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();
|
|
@@ -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)) {
|
|
@@ -20,6 +20,6 @@ export default class ENTimeUnitAgoFormatParser extends AbstractParserWithWordBou
|
|
|
20
20
|
const timeUnits = parseTimeUnits(match[1]);
|
|
21
21
|
const outputTimeUnits = reverseTimeUnits(timeUnits);
|
|
22
22
|
|
|
23
|
-
return ParsingComponents.
|
|
23
|
+
return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
|
|
24
24
|
}
|
|
25
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
|
}
|
|
@@ -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();
|
|
@@ -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
|
}
|
|
@@ -27,17 +27,17 @@ export default class NLRelativeDateFormatParser extends AbstractParserWithWordBo
|
|
|
27
27
|
if (modifier == "volgend" || modifier == "volgende" || modifier == "komende") {
|
|
28
28
|
const timeUnits = {};
|
|
29
29
|
timeUnits[timeunit] = 1;
|
|
30
|
-
return ParsingComponents.
|
|
30
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if (modifier == "afgelopen" || modifier == "vorige") {
|
|
34
34
|
const timeUnits = {};
|
|
35
35
|
timeUnits[timeunit] = -1;
|
|
36
|
-
return ParsingComponents.
|
|
36
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
const components = context.createParsingComponents();
|
|
40
|
-
let date = dayjs(context.
|
|
40
|
+
let date = dayjs(context.reference.instant);
|
|
41
41
|
|
|
42
42
|
// This week
|
|
43
43
|
if (unitWord.match(/week/i)) {
|
|
@@ -21,6 +21,6 @@ export default class NLTimeUnitAgoFormatParser extends AbstractParserWithWordBou
|
|
|
21
21
|
const timeUnits = parseTimeUnits(match[1]);
|
|
22
22
|
const outputTimeUnits = reverseTimeUnits(timeUnits);
|
|
23
23
|
|
|
24
|
-
return ParsingComponents.
|
|
24
|
+
return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -22,6 +22,6 @@ export default class NLTimeUnitCasualRelativeFormatParser extends AbstractParser
|
|
|
22
22
|
break;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
return ParsingComponents.
|
|
25
|
+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -22,6 +22,6 @@ export default class NLTimeUnitLaterFormatParser 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
|
}
|
|
@@ -10,6 +10,6 @@ export default class NLTimeUnitWithinFormatParser 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
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const NUMBER = {
|
|
2
|
+
"零": 0,
|
|
3
|
+
"一": 1,
|
|
4
|
+
"二": 2,
|
|
5
|
+
"兩": 2,
|
|
6
|
+
"三": 3,
|
|
7
|
+
"四": 4,
|
|
8
|
+
"五": 5,
|
|
9
|
+
"六": 6,
|
|
10
|
+
"七": 7,
|
|
11
|
+
"八": 8,
|
|
12
|
+
"九": 9,
|
|
13
|
+
"十": 10,
|
|
14
|
+
"廿": 20,
|
|
15
|
+
"卅": 30,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const WEEKDAY_OFFSET = {
|
|
19
|
+
"天": 0,
|
|
20
|
+
"日": 0,
|
|
21
|
+
"一": 1,
|
|
22
|
+
"二": 2,
|
|
23
|
+
"三": 3,
|
|
24
|
+
"四": 4,
|
|
25
|
+
"五": 5,
|
|
26
|
+
"六": 6,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export function zhStringToNumber(text: string) {
|
|
30
|
+
let number = 0;
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < text.length; i++) {
|
|
33
|
+
const char = text[i];
|
|
34
|
+
if (char === "十") {
|
|
35
|
+
number = number === 0 ? NUMBER[char] : number * NUMBER[char];
|
|
36
|
+
} else {
|
|
37
|
+
number += NUMBER[char];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function zhStringToYear(text: string) {
|
|
45
|
+
let string = "";
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < text.length; i++) {
|
|
48
|
+
const char = text[i];
|
|
49
|
+
string = string + NUMBER[char];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return parseInt(string);
|
|
53
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
import { ParsingContext } from "../../../../chrono";
|
|
3
|
+
import { AbstractParserWithWordBoundaryChecking } from "../../../../common/parsers/AbstractParserWithWordBoundary";
|
|
4
|
+
import { ParsingComponents, ParsingResult } from "../../../../results";
|
|
5
|
+
|
|
6
|
+
const NOW_GROUP = 1;
|
|
7
|
+
const DAY_GROUP_1 = 2;
|
|
8
|
+
const TIME_GROUP_1 = 3;
|
|
9
|
+
const TIME_GROUP_2 = 4;
|
|
10
|
+
const DAY_GROUP_3 = 5;
|
|
11
|
+
const TIME_GROUP_3 = 6;
|
|
12
|
+
|
|
13
|
+
export default class ZHHantCasualDateParser extends AbstractParserWithWordBoundaryChecking {
|
|
14
|
+
innerPattern(context: ParsingContext): RegExp {
|
|
15
|
+
return new RegExp(
|
|
16
|
+
"(而家|立(?:刻|即)|即刻)|" +
|
|
17
|
+
"(今|明|前|大前|後|大後|聽|昨|尋|琴)(早|朝|晚)|" +
|
|
18
|
+
"(上(?:午|晝)|朝(?:早)|早(?:上)|下(?:午|晝)|晏(?:晝)|晚(?:上)|夜(?:晚)?|中(?:午)|凌(?:晨))|" +
|
|
19
|
+
"(今|明|前|大前|後|大後|聽|昨|尋|琴)(?:日|天)" +
|
|
20
|
+
"(?:[\\s|,|,]*)" +
|
|
21
|
+
"(?:(上(?:午|晝)|朝(?:早)|早(?:上)|下(?:午|晝)|晏(?:晝)|晚(?:上)|夜(?:晚)?|中(?:午)|凌(?:晨)))?",
|
|
22
|
+
"i"
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents | ParsingResult {
|
|
27
|
+
const index = match.index;
|
|
28
|
+
const result = context.createParsingResult(index, match[0]);
|
|
29
|
+
|
|
30
|
+
const refMoment = dayjs(context.refDate);
|
|
31
|
+
let startMoment = refMoment;
|
|
32
|
+
|
|
33
|
+
if (match[NOW_GROUP]) {
|
|
34
|
+
result.start.imply("hour", refMoment.hour());
|
|
35
|
+
result.start.imply("minute", refMoment.minute());
|
|
36
|
+
result.start.imply("second", refMoment.second());
|
|
37
|
+
result.start.imply("millisecond", refMoment.millisecond());
|
|
38
|
+
} else if (match[DAY_GROUP_1]) {
|
|
39
|
+
const day1 = match[DAY_GROUP_1];
|
|
40
|
+
const time1 = match[TIME_GROUP_1];
|
|
41
|
+
|
|
42
|
+
if (day1 == "明" || day1 == "聽") {
|
|
43
|
+
// Check not "Tomorrow" on late night
|
|
44
|
+
if (refMoment.hour() > 1) {
|
|
45
|
+
startMoment = startMoment.add(1, "day");
|
|
46
|
+
}
|
|
47
|
+
} else if (day1 == "昨" || day1 == "尋" || day1 == "琴") {
|
|
48
|
+
startMoment = startMoment.add(-1, "day");
|
|
49
|
+
} else if (day1 == "前") {
|
|
50
|
+
startMoment = startMoment.add(-2, "day");
|
|
51
|
+
} else if (day1 == "大前") {
|
|
52
|
+
startMoment = startMoment.add(-3, "day");
|
|
53
|
+
} else if (day1 == "後") {
|
|
54
|
+
startMoment = startMoment.add(2, "day");
|
|
55
|
+
} else if (day1 == "大後") {
|
|
56
|
+
startMoment = startMoment.add(3, "day");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (time1 == "早" || time1 == "朝") {
|
|
60
|
+
result.start.imply("hour", 6);
|
|
61
|
+
} else if (time1 == "晚") {
|
|
62
|
+
result.start.imply("hour", 22);
|
|
63
|
+
result.start.imply("meridiem", 1);
|
|
64
|
+
}
|
|
65
|
+
} else if (match[TIME_GROUP_2]) {
|
|
66
|
+
const timeString2 = match[TIME_GROUP_2];
|
|
67
|
+
const time2 = timeString2[0];
|
|
68
|
+
if (time2 == "早" || time2 == "朝" || time2 == "上") {
|
|
69
|
+
result.start.imply("hour", 6);
|
|
70
|
+
} else if (time2 == "下" || time2 == "晏") {
|
|
71
|
+
result.start.imply("hour", 15);
|
|
72
|
+
result.start.imply("meridiem", 1);
|
|
73
|
+
} else if (time2 == "中") {
|
|
74
|
+
result.start.imply("hour", 12);
|
|
75
|
+
result.start.imply("meridiem", 1);
|
|
76
|
+
} else if (time2 == "夜" || time2 == "晚") {
|
|
77
|
+
result.start.imply("hour", 22);
|
|
78
|
+
result.start.imply("meridiem", 1);
|
|
79
|
+
} else if (time2 == "凌") {
|
|
80
|
+
result.start.imply("hour", 0);
|
|
81
|
+
}
|
|
82
|
+
} else if (match[DAY_GROUP_3]) {
|
|
83
|
+
const day3 = match[DAY_GROUP_3];
|
|
84
|
+
|
|
85
|
+
if (day3 == "明" || day3 == "聽") {
|
|
86
|
+
// Check not "Tomorrow" on late night
|
|
87
|
+
if (refMoment.hour() > 1) {
|
|
88
|
+
startMoment = startMoment.add(1, "day");
|
|
89
|
+
}
|
|
90
|
+
} else if (day3 == "昨" || day3 == "尋" || day3 == "琴") {
|
|
91
|
+
startMoment = startMoment.add(-1, "day");
|
|
92
|
+
} else if (day3 == "前") {
|
|
93
|
+
startMoment = startMoment.add(-2, "day");
|
|
94
|
+
} else if (day3 == "大前") {
|
|
95
|
+
startMoment = startMoment.add(-3, "day");
|
|
96
|
+
} else if (day3 == "後") {
|
|
97
|
+
startMoment = startMoment.add(2, "day");
|
|
98
|
+
} else if (day3 == "大後") {
|
|
99
|
+
startMoment = startMoment.add(3, "day");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const timeString3 = match[TIME_GROUP_3];
|
|
103
|
+
if (timeString3) {
|
|
104
|
+
const time3 = timeString3[0];
|
|
105
|
+
if (time3 == "早" || time3 == "朝" || time3 == "上") {
|
|
106
|
+
result.start.imply("hour", 6);
|
|
107
|
+
} else if (time3 == "下" || time3 == "晏") {
|
|
108
|
+
result.start.imply("hour", 15);
|
|
109
|
+
result.start.imply("meridiem", 1);
|
|
110
|
+
} else if (time3 == "中") {
|
|
111
|
+
result.start.imply("hour", 12);
|
|
112
|
+
result.start.imply("meridiem", 1);
|
|
113
|
+
} else if (time3 == "夜" || time3 == "晚") {
|
|
114
|
+
result.start.imply("hour", 22);
|
|
115
|
+
result.start.imply("meridiem", 1);
|
|
116
|
+
} else if (time3 == "凌") {
|
|
117
|
+
result.start.imply("hour", 0);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
result.start.assign("day", startMoment.date());
|
|
123
|
+
result.start.assign("month", startMoment.month() + 1);
|
|
124
|
+
result.start.assign("year", startMoment.year());
|
|
125
|
+
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
import { ParsingContext } from "../../../../chrono";
|
|
3
|
+
import { AbstractParserWithWordBoundaryChecking } from "../../../../common/parsers/AbstractParserWithWordBoundary";
|
|
4
|
+
import { NUMBER, zhStringToNumber, zhStringToYear } from "../constants";
|
|
5
|
+
|
|
6
|
+
const YEAR_GROUP = 1;
|
|
7
|
+
const MONTH_GROUP = 2;
|
|
8
|
+
const DAY_GROUP = 3;
|
|
9
|
+
|
|
10
|
+
export default class ZHHantDateParser extends AbstractParserWithWordBoundaryChecking {
|
|
11
|
+
innerPattern() {
|
|
12
|
+
// prettier-ignore
|
|
13
|
+
return new RegExp(
|
|
14
|
+
"(" +
|
|
15
|
+
"\\d{2,4}|" +
|
|
16
|
+
"[" + Object.keys(NUMBER).join("") + "]{4}|" +
|
|
17
|
+
"[" + Object.keys(NUMBER).join("") + "]{2}" +
|
|
18
|
+
")?"+
|
|
19
|
+
"(?:\\s*)" +
|
|
20
|
+
"(?:年)?" +
|
|
21
|
+
"(?:[\\s|,|,]*)" +
|
|
22
|
+
|
|
23
|
+
"(" +
|
|
24
|
+
"\\d{1,2}|"+
|
|
25
|
+
"[" +Object.keys(NUMBER).join("") +"]{1,2}"+
|
|
26
|
+
")" +
|
|
27
|
+
"(?:\\s*)" +
|
|
28
|
+
"(?:月)" +
|
|
29
|
+
"(?:\\s*)" +
|
|
30
|
+
"(" +
|
|
31
|
+
"\\d{1,2}|" +
|
|
32
|
+
"[" + Object.keys(NUMBER).join("") + "]{1,2}" +
|
|
33
|
+
")?" +
|
|
34
|
+
"(?:\\s*)" +
|
|
35
|
+
"(?:日|號)?"
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
innerExtract(context: ParsingContext, match: RegExpMatchArray) {
|
|
40
|
+
const startMoment = dayjs(context.refDate);
|
|
41
|
+
const result = context.createParsingResult(match.index, match[0]);
|
|
42
|
+
|
|
43
|
+
//Month
|
|
44
|
+
let month = parseInt(match[MONTH_GROUP]);
|
|
45
|
+
if (isNaN(month)) month = zhStringToNumber(match[MONTH_GROUP]);
|
|
46
|
+
result.start.assign("month", month);
|
|
47
|
+
|
|
48
|
+
//Day
|
|
49
|
+
if (match[DAY_GROUP]) {
|
|
50
|
+
let day = parseInt(match[DAY_GROUP]);
|
|
51
|
+
if (isNaN(day)) day = zhStringToNumber(match[DAY_GROUP]);
|
|
52
|
+
result.start.assign("day", day);
|
|
53
|
+
} else {
|
|
54
|
+
result.start.imply("day", startMoment.date());
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
//Year
|
|
58
|
+
if (match[YEAR_GROUP]) {
|
|
59
|
+
let year = parseInt(match[YEAR_GROUP]);
|
|
60
|
+
if (isNaN(year)) year = zhStringToYear(match[YEAR_GROUP]);
|
|
61
|
+
result.start.assign("year", year);
|
|
62
|
+
} else {
|
|
63
|
+
result.start.imply("year", startMoment.year());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
}
|