chrono-node 2.8.3 → 2.8.4

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.
Files changed (67) hide show
  1. package/dist/cjs/chrono.js +1 -1
  2. package/dist/cjs/chrono.js.map +1 -1
  3. package/dist/cjs/locales/en/refiners/ENMergeRelativeAfterDateRefiner.js +1 -1
  4. package/dist/cjs/locales/en/refiners/ENMergeRelativeAfterDateRefiner.js.map +1 -1
  5. package/dist/cjs/locales/en/refiners/ENMergeRelativeFollowByDateRefiner.js +1 -1
  6. package/dist/cjs/locales/en/refiners/ENMergeRelativeFollowByDateRefiner.js.map +1 -1
  7. package/dist/cjs/locales/it/refiners/ITMergeRelativeDateRefiner.js +1 -1
  8. package/dist/cjs/locales/it/refiners/ITMergeRelativeDateRefiner.js.map +1 -1
  9. package/dist/cjs/locales/sv/constants.d.ts +25 -0
  10. package/dist/cjs/locales/sv/constants.js +206 -0
  11. package/dist/cjs/locales/sv/constants.js.map +1 -0
  12. package/dist/cjs/locales/sv/index.d.ts +11 -0
  13. package/dist/cjs/locales/sv/index.js +50 -0
  14. package/dist/cjs/locales/sv/index.js.map +1 -0
  15. package/dist/cjs/locales/sv/parsers/SVCasualDateParser.d.ts +7 -0
  16. package/dist/cjs/locales/sv/parsers/SVCasualDateParser.js +134 -0
  17. package/dist/cjs/locales/sv/parsers/SVCasualDateParser.js.map +1 -0
  18. package/dist/cjs/locales/sv/parsers/SVMonthNameLittleEndianParser.d.ts +7 -0
  19. package/dist/cjs/locales/sv/parsers/SVMonthNameLittleEndianParser.js +49 -0
  20. package/dist/cjs/locales/sv/parsers/SVMonthNameLittleEndianParser.js.map +1 -0
  21. package/dist/cjs/locales/sv/parsers/SVWeekdayParser.d.ts +7 -0
  22. package/dist/cjs/locales/sv/parsers/SVWeekdayParser.js +40 -0
  23. package/dist/cjs/locales/sv/parsers/SVWeekdayParser.js.map +1 -0
  24. package/dist/cjs/results.d.ts +4 -2
  25. package/dist/cjs/results.js +12 -8
  26. package/dist/cjs/results.js.map +1 -1
  27. package/dist/esm/chrono.js +1 -1
  28. package/dist/esm/chrono.js.map +1 -1
  29. package/dist/esm/locales/en/refiners/ENMergeRelativeAfterDateRefiner.js +1 -1
  30. package/dist/esm/locales/en/refiners/ENMergeRelativeAfterDateRefiner.js.map +1 -1
  31. package/dist/esm/locales/en/refiners/ENMergeRelativeFollowByDateRefiner.js +1 -1
  32. package/dist/esm/locales/en/refiners/ENMergeRelativeFollowByDateRefiner.js.map +1 -1
  33. package/dist/esm/locales/it/refiners/ITMergeRelativeDateRefiner.js +1 -1
  34. package/dist/esm/locales/it/refiners/ITMergeRelativeDateRefiner.js.map +1 -1
  35. package/dist/esm/locales/sv/constants.d.ts +25 -0
  36. package/dist/esm/locales/sv/constants.js +199 -0
  37. package/dist/esm/locales/sv/constants.js.map +1 -0
  38. package/dist/esm/locales/sv/index.d.ts +11 -0
  39. package/dist/esm/locales/sv/index.js +36 -0
  40. package/dist/esm/locales/sv/index.js.map +1 -0
  41. package/dist/esm/locales/sv/parsers/SVCasualDateParser.d.ts +7 -0
  42. package/dist/esm/locales/sv/parsers/SVCasualDateParser.js +95 -0
  43. package/dist/esm/locales/sv/parsers/SVCasualDateParser.js.map +1 -0
  44. package/dist/esm/locales/sv/parsers/SVMonthNameLittleEndianParser.d.ts +7 -0
  45. package/dist/esm/locales/sv/parsers/SVMonthNameLittleEndianParser.js +46 -0
  46. package/dist/esm/locales/sv/parsers/SVMonthNameLittleEndianParser.js.map +1 -0
  47. package/dist/esm/locales/sv/parsers/SVWeekdayParser.d.ts +7 -0
  48. package/dist/esm/locales/sv/parsers/SVWeekdayParser.js +37 -0
  49. package/dist/esm/locales/sv/parsers/SVWeekdayParser.js.map +1 -0
  50. package/dist/esm/results.d.ts +4 -2
  51. package/dist/esm/results.js +12 -8
  52. package/dist/esm/results.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/chrono.ts +2 -2
  55. package/src/locales/en/refiners/ENMergeRelativeAfterDateRefiner.ts +1 -1
  56. package/src/locales/en/refiners/ENMergeRelativeFollowByDateRefiner.ts +1 -1
  57. package/src/locales/it/refiners/ITMergeRelativeDateRefiner.ts +1 -1
  58. package/src/locales/sv/constants.ts +215 -0
  59. package/src/locales/sv/index.ts +45 -0
  60. package/src/locales/sv/parsers/SVCasualDateParser.ts +114 -0
  61. package/src/locales/sv/parsers/SVMonthNameLittleEndianParser.ts +59 -0
  62. package/src/locales/sv/parsers/SVWeekdayParser.ts +47 -0
  63. package/src/results.ts +15 -8
  64. package/test/result.test.ts +4 -4
  65. package/test/sv/sv_casual.test.ts +45 -0
  66. package/test/sv/sv_weekday.test.ts +68 -0
  67. package/test/system_timezone.test.ts +36 -0
@@ -0,0 +1,59 @@
1
+ import { ParsingContext } from "../../../chrono";
2
+ import { ParsingResult } from "../../../results";
3
+ import { findYearClosestToRef } from "../../../calculation/years";
4
+ import { MONTH_DICTIONARY } from "../constants";
5
+ import { parseYear } from "../constants";
6
+ import { matchAnyPattern } from "../../../utils/pattern";
7
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
8
+
9
+ const PATTERN = new RegExp(
10
+ "(?:den\\s*?)?" +
11
+ `([0-9]{1,2})` +
12
+ `(?:\\s*(?:till|\\-|\\–|\\s)\\s*([0-9]{1,2}))?\\s*` +
13
+ `(${matchAnyPattern(MONTH_DICTIONARY)})` +
14
+ `(?:(?:-|/|,?\\s*)([0-9]{4}(?![^\\s]\\d)))?` +
15
+ `(?=\\W|$)`,
16
+ "i"
17
+ );
18
+
19
+ const DATE_GROUP = 1;
20
+ const DATE_TO_GROUP = 2;
21
+ const MONTH_NAME_GROUP = 3;
22
+ const YEAR_GROUP = 4;
23
+
24
+ export default class SVMonthNameLittleEndianParser extends AbstractParserWithWordBoundaryChecking {
25
+ innerPattern(): RegExp {
26
+ return PATTERN;
27
+ }
28
+
29
+ innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingResult {
30
+ const result = context.createParsingResult(match.index, match[0]);
31
+
32
+ const month = MONTH_DICTIONARY[match[MONTH_NAME_GROUP].toLowerCase()];
33
+ const day = parseInt(match[DATE_GROUP]);
34
+ if (day > 31) {
35
+ // e.g. "[96 Aug]" => "9[6 Aug]", we need to shift away from the next number
36
+ match.index = match.index + match[DATE_GROUP].length;
37
+ return null;
38
+ }
39
+
40
+ result.start.assign("month", month);
41
+ result.start.assign("day", day);
42
+
43
+ if (match[YEAR_GROUP]) {
44
+ const yearNumber = parseYear(match[YEAR_GROUP]);
45
+ result.start.assign("year", yearNumber);
46
+ } else {
47
+ const year = findYearClosestToRef(context.refDate, day, month);
48
+ result.start.imply("year", year);
49
+ }
50
+
51
+ if (match[DATE_TO_GROUP]) {
52
+ const endDate = parseInt(match[DATE_TO_GROUP]);
53
+ result.end = result.start.clone();
54
+ result.end.assign("day", endDate);
55
+ }
56
+
57
+ return result;
58
+ }
59
+ }
@@ -0,0 +1,47 @@
1
+ import { ParsingContext } from "../../../chrono";
2
+ import { ParsingComponents } from "../../../results";
3
+ import { WEEKDAY_DICTIONARY } from "../constants";
4
+ import { matchAnyPattern } from "../../../utils/pattern";
5
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
6
+ import { createParsingComponentsAtWeekday } from "../../../calculation/weekdays";
7
+
8
+ const PATTERN = new RegExp(
9
+ "(?:(?:\\,|\\(|\\()\\s*)?" +
10
+ "(?:på\\s*?)?" +
11
+ "(?:(förra|senaste|nästa|kommande)\\s*)?" +
12
+ `(${matchAnyPattern(WEEKDAY_DICTIONARY)})` +
13
+ "(?:\\s*(?:\\,|\\)|\\)))?" +
14
+ "(?:\\s*(förra|senaste|nästa|kommande)\\s*vecka)?" +
15
+ "(?=\\W|$)",
16
+ "i"
17
+ );
18
+
19
+ const PREFIX_GROUP = 1;
20
+ const SUFFIX_GROUP = 3;
21
+ const WEEKDAY_GROUP = 2;
22
+
23
+ export default class SVWeekdayParser extends AbstractParserWithWordBoundaryChecking {
24
+ innerPattern(): RegExp {
25
+ return PATTERN;
26
+ }
27
+
28
+ innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
29
+ const dayOfWeek = match[WEEKDAY_GROUP].toLowerCase();
30
+ const offset = WEEKDAY_DICTIONARY[dayOfWeek];
31
+ const prefix = match[PREFIX_GROUP];
32
+ const postfix = match[SUFFIX_GROUP];
33
+
34
+ let modifierWord = prefix || postfix;
35
+ modifierWord = modifierWord || "";
36
+ modifierWord = modifierWord.toLowerCase();
37
+
38
+ let modifier = null;
39
+ if (modifierWord.match(/förra|senaste/)) {
40
+ modifier = "last";
41
+ } else if (modifierWord.match(/nästa|kommande/)) {
42
+ modifier = "next";
43
+ }
44
+
45
+ return createParsingComponentsAtWeekday(context.reference, offset, modifier);
46
+ }
47
+ }
package/src/results.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Component, ParsedComponents, ParsedResult, ParsingReference } from "./types";
1
+ import { Component, ParsedComponents, ParsedResult, ParsingReference, TimezoneAbbrMap } from "./types";
2
2
 
3
3
  import quarterOfYear from "dayjs/plugin/quarterOfYear";
4
4
  import dayjs, { QUnitType } from "dayjs";
@@ -11,15 +11,22 @@ export class ReferenceWithTimezone {
11
11
  readonly instant: Date;
12
12
  readonly timezoneOffset?: number | null;
13
13
 
14
- constructor(input?: ParsingReference | Date) {
15
- input = input ?? new Date();
14
+ constructor(instant?: Date, timezoneOffset?: number) {
15
+ this.instant = instant ?? new Date();
16
+ this.timezoneOffset = timezoneOffset ?? null;
17
+ }
18
+
19
+ static fromDate(date: Date): ReferenceWithTimezone {
20
+ return new ReferenceWithTimezone(date);
21
+ }
22
+
23
+ static fromInput(input?: ParsingReference | Date, timezoneOverrides?: TimezoneAbbrMap) {
16
24
  if (input instanceof Date) {
17
- this.instant = input;
18
- this.timezoneOffset = null;
19
- } else {
20
- this.instant = input.instant ?? new Date();
21
- this.timezoneOffset = toTimezoneOffset(input.timezone, this.instant);
25
+ return ReferenceWithTimezone.fromDate(input);
22
26
  }
27
+ const instant: Date = input?.instant ?? new Date();
28
+ const timezoneOffset = toTimezoneOffset(input?.timezone, instant, timezoneOverrides);
29
+ return new ReferenceWithTimezone(instant, timezoneOffset);
23
30
  }
24
31
 
25
32
  /**
@@ -1,7 +1,7 @@
1
1
  import { ParsingComponents, ParsingResult, ReferenceWithTimezone } from "../src/results";
2
2
 
3
3
  test("Test - Create & manipulate parsing components", () => {
4
- const reference = new ReferenceWithTimezone(new Date());
4
+ const reference = ReferenceWithTimezone.fromDate(new Date());
5
5
  const components = new ParsingComponents(reference, { year: 2014, month: 11, day: 24 });
6
6
 
7
7
  expect(components.get("year")).toBe(2014);
@@ -178,21 +178,21 @@ test("Test - Checking non-existing date during DST skip", () => {
178
178
 
179
179
  test("Test - Getting timezone adjust date from references", () => {
180
180
  {
181
- const reference = new ReferenceWithTimezone({
181
+ const reference = ReferenceWithTimezone.fromInput({
182
182
  instant: new Date("Wed Jun 09 2021 07:21:32 GMT+0900 (JST)"),
183
183
  timezone: 9 * 60,
184
184
  });
185
185
  expect(reference.getDateWithAdjustedTimezone()).toStrictEqual(new Date(2021, 6 - 1, 9, 7, 21, 32));
186
186
  }
187
187
  {
188
- const reference = new ReferenceWithTimezone({
188
+ const reference = ReferenceWithTimezone.fromInput({
189
189
  instant: new Date("Wed Jun 09 2021 07:21:32 GMT+0900 (JST)"),
190
190
  timezone: "JST",
191
191
  });
192
192
  expect(reference.getDateWithAdjustedTimezone()).toStrictEqual(new Date(2021, 6 - 1, 9, 7, 21, 32));
193
193
  }
194
194
  {
195
- const reference = new ReferenceWithTimezone({
195
+ const reference = ReferenceWithTimezone.fromInput({
196
196
  instant: new Date("Wed Jun 09 2021 07:21:32 GMT-0500 (CDT)"),
197
197
  timezone: "CDT",
198
198
  });
@@ -0,0 +1,45 @@
1
+ import * as chrono from "../../src/locales/sv";
2
+ import { testSingleCase } from "../test_util";
3
+
4
+ test("Test - Single Expression", function () {
5
+ testSingleCase(chrono, "idag", new Date(2012, 7, 10), (result) => {
6
+ expect(result.start.get("year")).toBe(2012);
7
+ expect(result.start.get("month")).toBe(8);
8
+ expect(result.start.get("day")).toBe(10);
9
+ });
10
+
11
+ testSingleCase(chrono, "imorgon", new Date(2012, 7, 10), (result) => {
12
+ expect(result.start.get("year")).toBe(2012);
13
+ expect(result.start.get("month")).toBe(8);
14
+ expect(result.start.get("day")).toBe(11);
15
+ });
16
+
17
+ testSingleCase(chrono, "igår", new Date(2012, 7, 10), (result) => {
18
+ expect(result.start.get("year")).toBe(2012);
19
+ expect(result.start.get("month")).toBe(8);
20
+ expect(result.start.get("day")).toBe(9);
21
+ });
22
+
23
+ testSingleCase(chrono, "förrgår", new Date(2012, 7, 10), (result) => {
24
+ expect(result.start.get("year")).toBe(2012);
25
+ expect(result.start.get("month")).toBe(8);
26
+ expect(result.start.get("day")).toBe(8);
27
+ });
28
+ });
29
+
30
+ test("Test - Combined Expression", function () {
31
+ testSingleCase(chrono, "idag på morgonen", new Date(2012, 7, 10), (result) => {
32
+ expect(result.start.get("year")).toBe(2012);
33
+ expect(result.start.get("month")).toBe(8);
34
+ expect(result.start.get("day")).toBe(10);
35
+ expect(result.start.get("hour")).toBe(6);
36
+ });
37
+
38
+ // Denna funktionalitet behöver ytterligare utveckling
39
+ // testSingleCase(chrono, "imorgon kväll", new Date(2012, 7, 10), (result) => {
40
+ // expect(result.start.get("year")).toBe(2012);
41
+ // expect(result.start.get("month")).toBe(8);
42
+ // expect(result.start.get("day")).toBe(11);
43
+ // expect(result.start.get("hour")).toBe(20);
44
+ // });
45
+ });
@@ -0,0 +1,68 @@
1
+ import * as chrono from "../../src/locales/sv";
2
+ import { testSingleCase } from "../test_util";
3
+
4
+ test("Test - Single Expression", function () {
5
+ testSingleCase(chrono, "måndag", new Date(2012, 7, 9), (result) => {
6
+ expect(result.index).toBe(0);
7
+ expect(result.text).toBe("måndag");
8
+
9
+ expect(result.start).not.toBeNull();
10
+ expect(result.start.get("year")).toBe(2012);
11
+ expect(result.start.get("month")).toBe(8);
12
+ expect(result.start.get("day")).toBe(6);
13
+ expect(result.start.get("weekday")).toBe(1);
14
+ });
15
+
16
+ testSingleCase(chrono, "på måndag", new Date(2012, 7, 9), (result) => {
17
+ expect(result.index).toBe(0);
18
+ expect(result.text).toBe("på måndag");
19
+
20
+ expect(result.start).not.toBeNull();
21
+ expect(result.start.get("year")).toBe(2012);
22
+ expect(result.start.get("month")).toBe(8);
23
+ expect(result.start.get("day")).toBe(6);
24
+ expect(result.start.get("weekday")).toBe(1);
25
+ });
26
+ });
27
+
28
+ test("Test - Next/Last Week Expression", function () {
29
+ testSingleCase(chrono, "nästa måndag", new Date(2012, 7, 9), (result) => {
30
+ expect(result.index).toBe(0);
31
+ expect(result.text).toBe("nästa måndag");
32
+
33
+ expect(result.start).not.toBeNull();
34
+ expect(result.start.get("year")).toBe(2012);
35
+ expect(result.start.get("month")).toBe(8);
36
+ expect(result.start.get("day")).toBe(13);
37
+ expect(result.start.get("weekday")).toBe(1);
38
+ });
39
+
40
+ testSingleCase(chrono, "förra måndag", new Date(2012, 7, 9), (result) => {
41
+ expect(result.index).toBe(0);
42
+ expect(result.text).toBe("förra måndag");
43
+
44
+ expect(result.start).not.toBeNull();
45
+ expect(result.start.get("year")).toBe(2012);
46
+ expect(result.start.get("month")).toBe(8);
47
+ expect(result.start.get("day")).toBe(6);
48
+ expect(result.start.get("weekday")).toBe(1);
49
+ });
50
+ });
51
+
52
+ test("Test - Weekday variations", function () {
53
+ testSingleCase(chrono, "söndag", new Date(2012, 7, 9), (result) => {
54
+ expect(result.start.get("weekday")).toBe(0);
55
+ });
56
+
57
+ testSingleCase(chrono, "tisdag", new Date(2012, 7, 9), (result) => {
58
+ expect(result.start.get("weekday")).toBe(2);
59
+ });
60
+
61
+ testSingleCase(chrono, "fredag", new Date(2012, 7, 9), (result) => {
62
+ expect(result.start.get("weekday")).toBe(5);
63
+ });
64
+
65
+ testSingleCase(chrono, "lördag", new Date(2012, 7, 9), (result) => {
66
+ expect(result.start.get("weekday")).toBe(6);
67
+ });
68
+ });
@@ -70,6 +70,42 @@ test("Test - Using reference instance with different timezone", function () {
70
70
  });
71
71
  });
72
72
 
73
+ test("Test - Using reference instance with custom timezones", function () {
74
+ // Sun Jun 06 2021 19:00:00 GMT+0900 (JST)
75
+ // Sun Jun 06 2021 11:00:00 GMT+0100 (BST)
76
+ const refInstant = new Date("Sun Jun 06 2021 19:00:00 GMT+0900 (JST)");
77
+
78
+ // Fictional timezones
79
+ const timezones = {
80
+ "JJJ": 540, // JJJ => GMT+0900 JST
81
+ "BBB": 60, // BBB => GMT+0100 BST
82
+ };
83
+
84
+ // "At 4pm tomorrow" at "Sun Jun 06 2021 11:00:00 (BBB = BST)"
85
+ testSingleCase(
86
+ chrono,
87
+ "At 4pm tomorrow",
88
+ { instant: refInstant, timezone: "BBB" },
89
+ { timezones: timezones },
90
+ (result) => {
91
+ const expectedInstant = new Date("Mon Jun 07 2021 16:00:00 GMT+0100 (BST)");
92
+ expect(result).toBeDate(expectedInstant);
93
+ }
94
+ );
95
+
96
+ // "At 4pm tomorrow" at "Sun Jun 06 2021 19:00:00 (JJJ = JST)"
97
+ testSingleCase(
98
+ chrono,
99
+ "At 4pm tomorrow",
100
+ { instant: refInstant, timezone: "JJJ" },
101
+ { timezones: timezones },
102
+ (result) => {
103
+ const expectedInstant = new Date("Mon Jun 07 2021 16:00:00 GMT+0900 (JST)");
104
+ expect(result).toBeDate(expectedInstant);
105
+ }
106
+ );
107
+ });
108
+
73
109
  test("Test - Timezone difference on reference date #2", function () {
74
110
  const refInstant = new Date("2024-02-21T10:00:00+1300");
75
111