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
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chrono components for zh support
|
|
3
|
+
* TODO: Complete general zh support (current support only zh-Hant)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Chrono, Configuration } from "../../chrono";
|
|
7
|
+
import ExtractTimezoneOffsetRefiner from "../../common/refiners/ExtractTimezoneOffsetRefiner";
|
|
8
|
+
import { includeCommonConfiguration } from "../../configurations";
|
|
9
|
+
import { ParsedResult, ParsingOption } from "../../index";
|
|
10
|
+
import ZHHantCasualDateParser from "./hant/parsers/ZHHantCasualDateParser";
|
|
11
|
+
import ZHHantDateParser from "./hant/parsers/ZHHantDateParser";
|
|
12
|
+
import ZHHantDeadlineFormatParser from "./hant/parsers/ZHHantDeadlineFormatParser";
|
|
13
|
+
import ZHHantRelationWeekdayParser from "./hant/parsers/ZHHantRelationWeekdayParser";
|
|
14
|
+
import ZHHantTimeExpressionParser from "./hant/parsers/ZHHantTimeExpressionParser";
|
|
15
|
+
import ZHHantWeekdayParser from "./hant/parsers/ZHHantWeekdayParser";
|
|
16
|
+
import ZHHantMergeDateRangeRefiner from "./hant/refiners/ZHHantMergeDateRangeRefiner";
|
|
17
|
+
import ZHHantMergeDateTimeRefiner from "./hant/refiners/ZHHantMergeDateTimeRefiner";
|
|
18
|
+
|
|
19
|
+
// Shortcuts
|
|
20
|
+
export const hant = new Chrono(createCasualConfiguration());
|
|
21
|
+
|
|
22
|
+
export const casual = new Chrono(createCasualConfiguration());
|
|
23
|
+
export const strict = new Chrono(createConfiguration());
|
|
24
|
+
|
|
25
|
+
export function parse(text: string, ref?: Date, option?: ParsingOption): ParsedResult[] {
|
|
26
|
+
return casual.parse(text, ref, option);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function parseDate(text: string, ref?: Date, option?: ParsingOption): Date {
|
|
30
|
+
return casual.parseDate(text, ref, option);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @ignore (to be documented later)
|
|
35
|
+
*/
|
|
36
|
+
export function createCasualConfiguration(): Configuration {
|
|
37
|
+
const option = createConfiguration();
|
|
38
|
+
option.parsers.unshift(new ZHHantCasualDateParser());
|
|
39
|
+
return option;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @ignore (to be documented later)
|
|
44
|
+
*/
|
|
45
|
+
export function createConfiguration(): Configuration {
|
|
46
|
+
const configuration = includeCommonConfiguration({
|
|
47
|
+
parsers: [
|
|
48
|
+
new ZHHantDateParser(),
|
|
49
|
+
new ZHHantRelationWeekdayParser(),
|
|
50
|
+
new ZHHantWeekdayParser(),
|
|
51
|
+
new ZHHantTimeExpressionParser(),
|
|
52
|
+
new ZHHantDeadlineFormatParser(),
|
|
53
|
+
],
|
|
54
|
+
refiners: [new ZHHantMergeDateRangeRefiner(), new ZHHantMergeDateTimeRefiner()],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// REMOVE ExtractTimezoneOffsetRefiner
|
|
58
|
+
configuration.refiners = configuration.refiners.filter(
|
|
59
|
+
(refiner) => !(refiner instanceof ExtractTimezoneOffsetRefiner)
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
return configuration;
|
|
63
|
+
}
|
package/src/results.ts
CHANGED
|
@@ -8,7 +8,7 @@ dayjs.extend(quarterOfYear);
|
|
|
8
8
|
|
|
9
9
|
export class ReferenceWithTimezone {
|
|
10
10
|
readonly instant: Date;
|
|
11
|
-
readonly timezoneOffset
|
|
11
|
+
readonly timezoneOffset?: number;
|
|
12
12
|
|
|
13
13
|
constructor(input?: ParsingReference | Date) {
|
|
14
14
|
input = input ?? new Date();
|
|
@@ -17,7 +17,7 @@ export class ReferenceWithTimezone {
|
|
|
17
17
|
this.timezoneOffset = -input.getTimezoneOffset();
|
|
18
18
|
} else {
|
|
19
19
|
this.instant = input.instant ?? new Date();
|
|
20
|
-
this.timezoneOffset = toTimezoneOffset(input.timezone
|
|
20
|
+
this.timezoneOffset = toTimezoneOffset(input.timezone);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -142,7 +142,7 @@ export class ParsingComponents implements ParsedComponents {
|
|
|
142
142
|
|
|
143
143
|
date(): Date {
|
|
144
144
|
const date = this.dateWithoutTimezoneAdjustment();
|
|
145
|
-
return new Date(date.getTime() + this.getSystemTimezoneAdjustmentMinute() * 60000);
|
|
145
|
+
return new Date(date.getTime() + this.getSystemTimezoneAdjustmentMinute(date) * 60000);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
private dateWithoutTimezoneAdjustment() {
|
|
@@ -160,31 +160,41 @@ export class ParsingComponents implements ParsedComponents {
|
|
|
160
160
|
return date;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
private getSystemTimezoneAdjustmentMinute() {
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
private getSystemTimezoneAdjustmentMinute(date?: Date) {
|
|
164
|
+
if (!date || date.getTime() < 0) {
|
|
165
|
+
// Javascript date timezone calculation got effect when the time epoch < 0
|
|
166
|
+
// e.g. new Date('Tue Feb 02 1300 00:00:00 GMT+0900 (JST)') => Tue Feb 02 1300 00:18:59 GMT+0918 (JST)
|
|
167
|
+
date = new Date();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const currentTimezoneOffset = -date.getTimezoneOffset();
|
|
171
|
+
const targetTimezoneOffset =
|
|
172
|
+
this.get("timezoneOffset") ?? this.reference.timezoneOffset ?? currentTimezoneOffset;
|
|
166
173
|
|
|
167
174
|
return currentTimezoneOffset - targetTimezoneOffset;
|
|
168
175
|
}
|
|
169
176
|
|
|
170
|
-
static
|
|
171
|
-
|
|
177
|
+
static createRelativeFromReference(
|
|
178
|
+
reference: ReferenceWithTimezone,
|
|
172
179
|
fragments: { [c in OpUnitType | QUnitType]?: number }
|
|
173
180
|
): ParsingComponents {
|
|
174
|
-
let date = dayjs(
|
|
181
|
+
let date = dayjs(reference.instant);
|
|
175
182
|
for (const key in fragments) {
|
|
176
183
|
date = date.add(fragments[key as OpUnitType], key as OpUnitType);
|
|
177
184
|
}
|
|
178
185
|
|
|
179
|
-
const reference = new ReferenceWithTimezone(refInstant);
|
|
180
186
|
const components = new ParsingComponents(reference);
|
|
181
187
|
if (fragments["hour"] || fragments["minute"] || fragments["second"]) {
|
|
182
188
|
assignSimilarTime(components, date);
|
|
183
189
|
assignSimilarDate(components, date);
|
|
184
|
-
|
|
190
|
+
if (reference.timezoneOffset !== null) {
|
|
191
|
+
components.assign("timezoneOffset", -reference.instant.getTimezoneOffset());
|
|
192
|
+
}
|
|
185
193
|
} else {
|
|
186
194
|
implySimilarTime(components, date);
|
|
187
|
-
|
|
195
|
+
if (reference.timezoneOffset !== null) {
|
|
196
|
+
components.imply("timezoneOffset", -reference.instant.getTimezoneOffset());
|
|
197
|
+
}
|
|
188
198
|
|
|
189
199
|
if (fragments["d"]) {
|
|
190
200
|
components.assign("day", date.date());
|
package/src/timezone.ts
CHANGED
|
@@ -192,7 +192,11 @@ export const TIMEZONE_ABBR_MAP = {
|
|
|
192
192
|
YEKT: 360,
|
|
193
193
|
};
|
|
194
194
|
|
|
195
|
-
export function toTimezoneOffset(timezoneInput: string | number): number {
|
|
195
|
+
export function toTimezoneOffset(timezoneInput: string | number): number | null {
|
|
196
|
+
if (timezoneInput === null) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
|
|
196
200
|
if (typeof timezoneInput === "number") {
|
|
197
201
|
return timezoneInput;
|
|
198
202
|
}
|
package/src/utils/dayjs.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ParsingComponents } from "../results";
|
|
2
2
|
import dayjs from "dayjs";
|
|
3
|
+
import { Meridiem } from "../index";
|
|
3
4
|
|
|
4
5
|
export function assignTheNextDay(component: ParsingComponents, targetDayJs: dayjs.Dayjs) {
|
|
5
6
|
targetDayJs = targetDayJs.add(1, "day");
|
|
@@ -18,6 +19,11 @@ export function assignSimilarTime(component: ParsingComponents, targetDayJs: day
|
|
|
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", Meridiem.AM);
|
|
24
|
+
} else {
|
|
25
|
+
component.assign("meridiem", Meridiem.PM);
|
|
26
|
+
}
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
export function implySimilarTime(component: ParsingComponents, targetDayJs: dayjs.Dayjs) {
|
|
@@ -21,6 +21,17 @@ test("Test - Single Expression", () => {
|
|
|
21
21
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 8, 9, 10, 11));
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
+
testSingleCase(
|
|
25
|
+
chrono.casual,
|
|
26
|
+
"The Deadline is now, without implicit local timezone",
|
|
27
|
+
{ instant: new Date(1637674343000), timezone: null },
|
|
28
|
+
(result) => {
|
|
29
|
+
expect(result.text).toBe("now");
|
|
30
|
+
expect(result.start).toBeDate(new Date(1637674343000));
|
|
31
|
+
expect(result.start.isCertain("timezoneOffset")).toBe(false);
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
24
35
|
testSingleCase(chrono.casual, "The Deadline is today", new Date(2012, 7, 10, 14, 12), (result) => {
|
|
25
36
|
expect(result.index).toBe(16);
|
|
26
37
|
expect(result.text).toBe("today");
|
|
@@ -364,6 +364,16 @@ test("Test - Forward Option", () => {
|
|
|
364
364
|
expect(result.end.get("day")).toBe(23);
|
|
365
365
|
expect(result.end.get("hour")).toBe(19);
|
|
366
366
|
});
|
|
367
|
+
|
|
368
|
+
testSingleCase(chrono, "17 August 2013 - 19 August 2013", (result) => {
|
|
369
|
+
expect(result.start.get("year")).toBe(2013);
|
|
370
|
+
expect(result.start.get("month")).toBe(8);
|
|
371
|
+
expect(result.start.get("day")).toBe(17);
|
|
372
|
+
|
|
373
|
+
expect(result.end.get("year")).toBe(2013);
|
|
374
|
+
expect(result.end.get("month")).toBe(8);
|
|
375
|
+
expect(result.end.get("day")).toBe(19);
|
|
376
|
+
});
|
|
367
377
|
});
|
|
368
378
|
|
|
369
379
|
test("Test - Impossible Dates (Strict Mode)", function () {
|
|
@@ -230,4 +230,12 @@ test("Test - Relative date components' certainty and imply timezone", () => {
|
|
|
230
230
|
expect(result).toBeDate(new Date("Sun Nov 29 2020 13:34:13 GMT+0900 (Japan Standard Time)"));
|
|
231
231
|
expect(result).toBeDate(new Date("Sun Nov 29 2020 5:34:13 GMT+0100"));
|
|
232
232
|
}
|
|
233
|
+
|
|
234
|
+
{
|
|
235
|
+
const text = "in 20 minutes";
|
|
236
|
+
const result = chrono.parse(text, { instant: refDate, timezone: null })[0] as ParsingResult;
|
|
237
|
+
|
|
238
|
+
expect(result.text).toBe(text);
|
|
239
|
+
expect(result.start.isCertain("timezoneOffset")).toBe(false);
|
|
240
|
+
}
|
|
233
241
|
});
|
package/test/en/en_slash.test.ts
CHANGED
|
@@ -203,4 +203,15 @@ test("Test - forward dates only option", function () {
|
|
|
203
203
|
|
|
204
204
|
expect(result.start).toBeDate(new Date(2000, 5 - 1, 31, 12));
|
|
205
205
|
});
|
|
206
|
+
|
|
207
|
+
testSingleCase(chrono, "1/8 at 12pm", new Date("Sep 25 2021 12:00:00"), { forwardDate: true }, (result) => {
|
|
208
|
+
expect(result.text).toBe("1/8 at 12pm");
|
|
209
|
+
|
|
210
|
+
expect(result.start).not.toBeNull();
|
|
211
|
+
expect(result.start.get("year")).toBe(2022);
|
|
212
|
+
expect(result.start.get("month")).toBe(1);
|
|
213
|
+
expect(result.start.get("day")).toBe(8);
|
|
214
|
+
|
|
215
|
+
expect(result.start).toBeDate(new Date(2022, 1 - 1, 8, 12));
|
|
216
|
+
});
|
|
206
217
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as chrono from "../../src/";
|
|
2
2
|
import { testSingleCase, testUnexpectedResult } from "../test_util";
|
|
3
|
+
import { Meridiem } from "../../src/";
|
|
3
4
|
|
|
4
5
|
test("Test - Single Expression", function () {
|
|
5
6
|
testSingleCase(chrono, "5 days ago, we did something", new Date(2012, 7, 10), (result) => {
|
|
@@ -31,6 +32,7 @@ test("Test - Single Expression", function () {
|
|
|
31
32
|
expect(result.text).toBe("15 minute ago");
|
|
32
33
|
expect(result.start.get("hour")).toBe(11);
|
|
33
34
|
expect(result.start.get("minute")).toBe(59);
|
|
35
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
34
36
|
|
|
35
37
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 11, 59));
|
|
36
38
|
});
|
|
@@ -40,6 +42,7 @@ test("Test - Single Expression", function () {
|
|
|
40
42
|
expect(result.text).toBe("15 minute earlier");
|
|
41
43
|
expect(result.start.get("hour")).toBe(11);
|
|
42
44
|
expect(result.start.get("minute")).toBe(59);
|
|
45
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
43
46
|
|
|
44
47
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 11, 59));
|
|
45
48
|
});
|
|
@@ -49,6 +52,7 @@ test("Test - Single Expression", function () {
|
|
|
49
52
|
expect(result.text).toBe("15 minute before");
|
|
50
53
|
expect(result.start.get("hour")).toBe(11);
|
|
51
54
|
expect(result.start.get("minute")).toBe(59);
|
|
55
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
52
56
|
|
|
53
57
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 11, 59));
|
|
54
58
|
});
|
|
@@ -58,6 +62,7 @@ test("Test - Single Expression", function () {
|
|
|
58
62
|
expect(result.text).toBe("12 hours ago");
|
|
59
63
|
expect(result.start.get("hour")).toBe(0);
|
|
60
64
|
expect(result.start.get("minute")).toBe(14);
|
|
65
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
61
66
|
|
|
62
67
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 0, 14));
|
|
63
68
|
});
|
|
@@ -67,6 +72,7 @@ test("Test - Single Expression", function () {
|
|
|
67
72
|
expect(result.text).toBe("1h ago");
|
|
68
73
|
expect(result.start.get("hour")).toBe(11);
|
|
69
74
|
expect(result.start.get("minute")).toBe(14);
|
|
75
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
70
76
|
});
|
|
71
77
|
|
|
72
78
|
testSingleCase(chrono, "1hr ago", new Date(2012, 7, 10, 12, 14), (result) => {
|
|
@@ -74,6 +80,7 @@ test("Test - Single Expression", function () {
|
|
|
74
80
|
expect(result.text).toBe("1hr ago");
|
|
75
81
|
expect(result.start.get("hour")).toBe(11);
|
|
76
82
|
expect(result.start.get("minute")).toBe(14);
|
|
83
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
77
84
|
});
|
|
78
85
|
|
|
79
86
|
testSingleCase(chrono, " half an hour ago", new Date(2012, 7, 10, 12, 14), (result) => {
|
|
@@ -81,6 +88,7 @@ test("Test - Single Expression", function () {
|
|
|
81
88
|
expect(result.text).toBe("half an hour ago");
|
|
82
89
|
expect(result.start.get("hour")).toBe(11);
|
|
83
90
|
expect(result.start.get("minute")).toBe(44);
|
|
91
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
84
92
|
|
|
85
93
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 11, 44));
|
|
86
94
|
});
|
|
@@ -90,6 +98,7 @@ test("Test - Single Expression", function () {
|
|
|
90
98
|
expect(result.text).toBe("12 hours ago");
|
|
91
99
|
expect(result.start.get("hour")).toBe(0);
|
|
92
100
|
expect(result.start.get("minute")).toBe(14);
|
|
101
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
93
102
|
|
|
94
103
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 0, 14));
|
|
95
104
|
});
|
|
@@ -100,6 +109,7 @@ test("Test - Single Expression", function () {
|
|
|
100
109
|
expect(result.start.get("hour")).toBe(12);
|
|
101
110
|
expect(result.start.get("minute")).toBe(13);
|
|
102
111
|
expect(result.start.get("second")).toBe(48);
|
|
112
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.PM);
|
|
103
113
|
|
|
104
114
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 12, 13, 48));
|
|
105
115
|
});
|
|
@@ -110,6 +120,7 @@ test("Test - Single Expression", function () {
|
|
|
110
120
|
expect(result.start.get("hour")).toBe(12);
|
|
111
121
|
expect(result.start.get("minute")).toBe(13);
|
|
112
122
|
expect(result.start.get("second")).toBe(57);
|
|
123
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.PM);
|
|
113
124
|
|
|
114
125
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 12, 13, 57));
|
|
115
126
|
});
|
|
@@ -131,6 +142,7 @@ test("Test - Single Expression", function () {
|
|
|
131
142
|
expect(result.text).toBe("half An hour ago");
|
|
132
143
|
expect(result.start.get("hour")).toBe(11);
|
|
133
144
|
expect(result.start.get("minute")).toBe(44);
|
|
145
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
134
146
|
|
|
135
147
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 11, 44));
|
|
136
148
|
});
|
|
@@ -152,6 +164,7 @@ test("Test - Single Expression", function () {
|
|
|
152
164
|
expect(result.text).toBe("a min before");
|
|
153
165
|
expect(result.start.get("hour")).toBe(12);
|
|
154
166
|
expect(result.start.get("minute")).toBe(13);
|
|
167
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.PM);
|
|
155
168
|
|
|
156
169
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 12, 13));
|
|
157
170
|
});
|
|
@@ -213,6 +226,7 @@ test("Test - Nested time ago", function () {
|
|
|
213
226
|
expect(result.start.get("day")).toBe(10);
|
|
214
227
|
expect(result.start.get("hour")).toBe(7);
|
|
215
228
|
expect(result.start.get("minute")).toBe(1);
|
|
229
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
216
230
|
});
|
|
217
231
|
|
|
218
232
|
testSingleCase(chrono, "1 day 21 hours ago ", new Date(2012, 7, 10, 22, 30), (result) => {
|
|
@@ -220,6 +234,7 @@ test("Test - Nested time ago", function () {
|
|
|
220
234
|
expect(result.start.get("day")).toBe(9);
|
|
221
235
|
expect(result.start.get("hour")).toBe(1);
|
|
222
236
|
expect(result.start.get("minute")).toBe(30);
|
|
237
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
223
238
|
});
|
|
224
239
|
|
|
225
240
|
testSingleCase(chrono, "3 min 49 sec ago ", new Date(2012, 7, 10, 22, 30), (result) => {
|
|
@@ -228,6 +243,7 @@ test("Test - Nested time ago", function () {
|
|
|
228
243
|
expect(result.start.get("hour")).toBe(22);
|
|
229
244
|
expect(result.start.get("minute")).toBe(26);
|
|
230
245
|
expect(result.start.get("second")).toBe(11);
|
|
246
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.PM);
|
|
231
247
|
});
|
|
232
248
|
});
|
|
233
249
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as chrono from "../../src/";
|
|
2
2
|
import { testSingleCase } from "../test_util";
|
|
3
|
+
import { Meridiem } from "../../src/";
|
|
3
4
|
|
|
4
5
|
test("Test - Later Expression", function () {
|
|
5
6
|
testSingleCase(chrono, "2 days later", new Date(2012, 7, 10, 12), (result) => {
|
|
@@ -77,6 +78,7 @@ test("Test - From now Expression", () => {
|
|
|
77
78
|
expect(result.text).toBe("15 minute from now");
|
|
78
79
|
expect(result.start.get("hour")).toBe(12);
|
|
79
80
|
expect(result.start.get("minute")).toBe(29);
|
|
81
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.PM);
|
|
80
82
|
|
|
81
83
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 12, 29));
|
|
82
84
|
});
|
|
@@ -86,6 +88,7 @@ test("Test - From now Expression", () => {
|
|
|
86
88
|
expect(result.text).toBe("15 minutes earlier");
|
|
87
89
|
expect(result.start.get("hour")).toBe(11);
|
|
88
90
|
expect(result.start.get("minute")).toBe(59);
|
|
91
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
89
92
|
|
|
90
93
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 11, 59));
|
|
91
94
|
});
|
|
@@ -95,6 +98,7 @@ test("Test - From now Expression", () => {
|
|
|
95
98
|
expect(result.text).toBe("15 minute out");
|
|
96
99
|
expect(result.start.get("hour")).toBe(12);
|
|
97
100
|
expect(result.start.get("minute")).toBe(29);
|
|
101
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.PM);
|
|
98
102
|
|
|
99
103
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 12, 29));
|
|
100
104
|
});
|
|
@@ -115,6 +119,7 @@ test("Test - From now Expression", () => {
|
|
|
115
119
|
expect(result.start.get("day")).toBe(11);
|
|
116
120
|
expect(result.start.get("hour")).toBe(0);
|
|
117
121
|
expect(result.start.get("minute")).toBe(14);
|
|
122
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.AM);
|
|
118
123
|
});
|
|
119
124
|
|
|
120
125
|
testSingleCase(chrono, " half an hour from now", new Date(2012, 7, 10, 12, 14), (result) => {
|
|
@@ -122,6 +127,7 @@ test("Test - From now Expression", () => {
|
|
|
122
127
|
expect(result.text).toBe("half an hour from now");
|
|
123
128
|
expect(result.start.get("hour")).toBe(12);
|
|
124
129
|
expect(result.start.get("minute")).toBe(44);
|
|
130
|
+
expect(result.start.get("meridiem")).toBe(Meridiem.PM);
|
|
125
131
|
|
|
126
132
|
expect(result.start).toBeDate(new Date(2012, 7, 10, 12, 44));
|
|
127
133
|
});
|
|
@@ -81,20 +81,95 @@ test("Test - Parsing date with timezone abbreviation", function () {
|
|
|
81
81
|
});
|
|
82
82
|
|
|
83
83
|
test("Test - Not parsing timezone from relative time", function () {
|
|
84
|
-
|
|
84
|
+
{
|
|
85
|
+
const refInstant = new Date("Sun Nov 29 2020 13:24:13 GMT+0900 (Japan Standard Time)");
|
|
86
|
+
const expectedInstant = new Date("Sun Nov 29 2020 14:24:13 GMT+0900 (Japan Standard Time)");
|
|
87
|
+
|
|
88
|
+
testSingleCase(chrono, "in 1 hour get eggs and milk", refInstant, (result, text) => {
|
|
89
|
+
expect(result.text).toBe("in 1 hour");
|
|
90
|
+
expect(result.start.get("timezoneOffset")).toBe(-refInstant.getTimezoneOffset());
|
|
91
|
+
expect(result.start).toBeDate(expectedInstant);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
{
|
|
96
|
+
const refInstant = new Date("Sun Nov 29 2020 13:24:13 GMT+0900 (Japan Standard Time)");
|
|
97
|
+
const expectedInstant = new Date("Sun Nov 29 2020 14:24:13 GMT+0900 (Japan Standard Time)");
|
|
98
|
+
|
|
99
|
+
testSingleCase(chrono, "in 1 hour GMT", refInstant, (result, text) => {
|
|
100
|
+
expect(result.text).toBe("in 1 hour");
|
|
101
|
+
expect(result.start).toBeDate(expectedInstant);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
{
|
|
106
|
+
const refInstant = new Date("Sun Nov 29 2020 13:24:13 GMT+0900 (Japan Standard Time)");
|
|
107
|
+
const expectedInstant = new Date("Sun Nov 29 2020 14:24:13 GMT+0900 (Japan Standard Time)");
|
|
108
|
+
|
|
109
|
+
testSingleCase(chrono, "in 1 hour GMT", { instant: refInstant, timezone: "JST" }, (result, text) => {
|
|
110
|
+
expect(result.text).toBe("in 1 hour");
|
|
111
|
+
expect(result.start).toBeDate(expectedInstant);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
{
|
|
116
|
+
const refInstant = new Date("Sun Nov 29 2020 13:24:13 GMT+0900 (Japan Standard Time)");
|
|
117
|
+
const expectedInstant = new Date("Sun Nov 29 2020 14:24:13 GMT+0900 (Japan Standard Time)");
|
|
118
|
+
|
|
119
|
+
testSingleCase(chrono, "in 1 hour GMT", { instant: refInstant, timezone: "BST" }, (result, text) => {
|
|
120
|
+
expect(result.text).toBe("in 1 hour");
|
|
121
|
+
expect(result.start).toBeDate(expectedInstant);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
});
|
|
85
125
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
126
|
+
test("Test - Relative time (Now) is not effected by timezone setting", function () {
|
|
127
|
+
const refInstant = new Date(1637674343000);
|
|
128
|
+
|
|
129
|
+
testSingleCase(chrono, "now", { instant: refInstant }, (result) => {
|
|
130
|
+
expect(result.text).toBe("now");
|
|
131
|
+
expect(result.start).toBeDate(refInstant);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
testSingleCase(chrono, "now", { instant: refInstant, timezone: null }, (result) => {
|
|
135
|
+
expect(result.text).toBe("now");
|
|
136
|
+
expect(result.start).toBeDate(refInstant);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
testSingleCase(chrono, "now", { instant: refInstant, timezone: "BST" }, (result) => {
|
|
140
|
+
expect(result.text).toBe("now");
|
|
141
|
+
expect(result.start).toBeDate(refInstant);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
testSingleCase(chrono, "now", { instant: refInstant, timezone: "JST" }, (result) => {
|
|
145
|
+
expect(result.text).toBe("now");
|
|
146
|
+
expect(result.start).toBeDate(refInstant);
|
|
89
147
|
});
|
|
148
|
+
});
|
|
90
149
|
|
|
91
|
-
|
|
92
|
-
|
|
150
|
+
test("Test - Relative time (2 hour later) is not effected by timezone setting", function () {
|
|
151
|
+
const refInstant = new Date(1637674343000);
|
|
152
|
+
const expectedInstant = new Date(1637674343000 + 2 * 60 * 60 * 1000);
|
|
93
153
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
154
|
+
testSingleCase(chrono, "2 hour later", { instant: refInstant }, (result) => {
|
|
155
|
+
expect(result.text).toBe("2 hour later");
|
|
156
|
+
expect(result.start).toBeDate(expectedInstant);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
testSingleCase(chrono, "2 hour later", { instant: refInstant, timezone: null }, (result) => {
|
|
160
|
+
expect(result.text).toBe("2 hour later");
|
|
161
|
+
expect(result.start).toBeDate(expectedInstant);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
testSingleCase(chrono, "2 hour later", { instant: refInstant, timezone: "BST" }, (result) => {
|
|
165
|
+
expect(result.text).toBe("2 hour later");
|
|
166
|
+
expect(result.start).toBeDate(expectedInstant);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
testSingleCase(chrono, "2 hour later", { instant: refInstant, timezone: "JST" }, (result) => {
|
|
170
|
+
expect(result.text).toBe("2 hour later");
|
|
171
|
+
expect(result.start).toBeDate(expectedInstant);
|
|
172
|
+
});
|
|
98
173
|
});
|
|
99
174
|
|
|
100
175
|
test("Test - Parsing timezone from relative date when valid", function () {
|
|
@@ -20,30 +20,6 @@ test("Test - Single Expression", function () {
|
|
|
20
20
|
expect(result.start).toBeDate(new Date(2012, 7, 6, 12));
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
testSingleCase(
|
|
24
|
-
chrono.casual,
|
|
25
|
-
"Monday (forward dates only)",
|
|
26
|
-
new Date(2012, 7, 9),
|
|
27
|
-
{ forwardDate: true },
|
|
28
|
-
(result) => {
|
|
29
|
-
expect(result.index).toBe(0);
|
|
30
|
-
expect(result.text).toBe("Monday");
|
|
31
|
-
|
|
32
|
-
expect(result.start).not.toBeNull();
|
|
33
|
-
expect(result.start.get("year")).toBe(2012);
|
|
34
|
-
expect(result.start.get("month")).toBe(8);
|
|
35
|
-
expect(result.start.get("day")).toBe(13);
|
|
36
|
-
expect(result.start.get("weekday")).toBe(1);
|
|
37
|
-
|
|
38
|
-
expect(result.start.isCertain("day")).toBe(false);
|
|
39
|
-
expect(result.start.isCertain("month")).toBe(false);
|
|
40
|
-
expect(result.start.isCertain("year")).toBe(false);
|
|
41
|
-
expect(result.start.isCertain("weekday")).toBe(true);
|
|
42
|
-
|
|
43
|
-
expect(result.start).toBeDate(new Date(2012, 7, 13, 12));
|
|
44
|
-
}
|
|
45
|
-
);
|
|
46
|
-
|
|
47
23
|
testSingleCase(chrono.casual, "Thursday", new Date(2012, 7, 9), (result) => {
|
|
48
24
|
expect(result.index).toBe(0);
|
|
49
25
|
expect(result.text).toBe("Thursday");
|
|
@@ -182,7 +158,31 @@ test("Test - Weekday Overlap", function () {
|
|
|
182
158
|
});
|
|
183
159
|
});
|
|
184
160
|
|
|
185
|
-
test("Test - forward dates only option",
|
|
161
|
+
test("Test - forward dates only option", () => {
|
|
162
|
+
testSingleCase(
|
|
163
|
+
chrono.casual,
|
|
164
|
+
"Monday (forward dates only)",
|
|
165
|
+
new Date(2012, 7, 9),
|
|
166
|
+
{ forwardDate: true },
|
|
167
|
+
(result) => {
|
|
168
|
+
expect(result.index).toBe(0);
|
|
169
|
+
expect(result.text).toBe("Monday");
|
|
170
|
+
|
|
171
|
+
expect(result.start).not.toBeNull();
|
|
172
|
+
expect(result.start.get("year")).toBe(2012);
|
|
173
|
+
expect(result.start.get("month")).toBe(8);
|
|
174
|
+
expect(result.start.get("day")).toBe(13);
|
|
175
|
+
expect(result.start.get("weekday")).toBe(1);
|
|
176
|
+
|
|
177
|
+
expect(result.start.isCertain("day")).toBe(false);
|
|
178
|
+
expect(result.start.isCertain("month")).toBe(false);
|
|
179
|
+
expect(result.start.isCertain("year")).toBe(false);
|
|
180
|
+
expect(result.start.isCertain("weekday")).toBe(true);
|
|
181
|
+
|
|
182
|
+
expect(result.start).toBeDate(new Date(2012, 7, 13, 12));
|
|
183
|
+
}
|
|
184
|
+
);
|
|
185
|
+
|
|
186
186
|
testSingleCase(
|
|
187
187
|
chrono.casual,
|
|
188
188
|
"this Friday to this Monday",
|
|
@@ -219,4 +219,48 @@ test("Test - forward dates only option", function () {
|
|
|
219
219
|
expect(result.end).toBeDate(new Date(2016, 8 - 1, 8, 12));
|
|
220
220
|
}
|
|
221
221
|
);
|
|
222
|
+
|
|
223
|
+
testSingleCase(
|
|
224
|
+
chrono.casual,
|
|
225
|
+
"sunday morning",
|
|
226
|
+
new Date("August 15, 2021, 20:00"),
|
|
227
|
+
{ forwardDate: true },
|
|
228
|
+
(result) => {
|
|
229
|
+
expect(result.index).toBe(0);
|
|
230
|
+
expect(result.text).toBe("sunday morning");
|
|
231
|
+
|
|
232
|
+
expect(result.start).not.toBeNull();
|
|
233
|
+
expect(result.start.get("year")).toBe(2021);
|
|
234
|
+
expect(result.start.get("month")).toBe(8);
|
|
235
|
+
expect(result.start.get("day")).toBe(22);
|
|
236
|
+
expect(result.start.get("weekday")).toBe(0);
|
|
237
|
+
|
|
238
|
+
expect(result.start.isCertain("day")).toBe(false);
|
|
239
|
+
expect(result.start.isCertain("month")).toBe(false);
|
|
240
|
+
expect(result.start.isCertain("year")).toBe(false);
|
|
241
|
+
expect(result.start.isCertain("weekday")).toBe(true);
|
|
242
|
+
|
|
243
|
+
expect(result.start).toBeDate(new Date(2021, 8 - 1, 22, 6));
|
|
244
|
+
}
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
testSingleCase(
|
|
248
|
+
chrono.casual,
|
|
249
|
+
"vacation monday - friday",
|
|
250
|
+
new Date("thursday 13 June 2019"),
|
|
251
|
+
{ forwardDate: true },
|
|
252
|
+
(result) => {
|
|
253
|
+
expect(result.text).toBe("monday - friday");
|
|
254
|
+
|
|
255
|
+
expect(result.start).not.toBeNull();
|
|
256
|
+
expect(result.start.get("year")).toBe(2019);
|
|
257
|
+
expect(result.start.get("month")).toBe(6);
|
|
258
|
+
expect(result.start.get("day")).toBe(17);
|
|
259
|
+
|
|
260
|
+
expect(result.end).not.toBeNull();
|
|
261
|
+
expect(result.end.get("year")).toBe(2019);
|
|
262
|
+
expect(result.end.get("month")).toBe(6);
|
|
263
|
+
expect(result.end.get("day")).toBe(21);
|
|
264
|
+
}
|
|
265
|
+
);
|
|
222
266
|
});
|
|
@@ -21,6 +21,8 @@ test("Test - Skip random non-date patterns", function () {
|
|
|
21
21
|
testUnexpectedResult(chrono, "Total: $1,194.09 [image: View Reservation");
|
|
22
22
|
|
|
23
23
|
testUnexpectedResult(chrono, "at 6.5 kilograms");
|
|
24
|
+
|
|
25
|
+
testUnexpectedResult(chrono, "ah that is unusual", null, { forwardDate: true });
|
|
24
26
|
});
|
|
25
27
|
|
|
26
28
|
test("Test - URLs % encoded", function () {
|
package/test/test_util.ts
CHANGED
|
@@ -61,10 +61,13 @@ export function testWithExpectedDate(chrono: ChronoLike, text: string, expectedD
|
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
export function testUnexpectedResult(chrono: ChronoLike, text: string, refDate?: Date) {
|
|
64
|
+
export function testUnexpectedResult(chrono: ChronoLike, text: string, refDate?: Date, options?: ParsingOption) {
|
|
65
65
|
const debugHandler = new BufferedDebugHandler();
|
|
66
|
+
options = options || {};
|
|
67
|
+
options.debug = debugHandler;
|
|
68
|
+
|
|
66
69
|
try {
|
|
67
|
-
const results = chrono.parse(text, refDate,
|
|
70
|
+
const results = chrono.parse(text, refDate, options);
|
|
68
71
|
expect(results).toHaveLength(0);
|
|
69
72
|
} catch (e) {
|
|
70
73
|
debugHandler.executeBufferedBlocks();
|