chrono-node 2.3.2 → 2.3.6

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 (134) hide show
  1. package/README.md +1 -1
  2. package/dist/common/casualReferences.js +3 -1
  3. package/dist/common/parsers/AbstractParserWithWordBoundary.js +2 -1
  4. package/dist/common/refiners/ExtractTimezoneAbbrRefiner.js +5 -0
  5. package/dist/index.d.ts +2 -1
  6. package/dist/index.js +3 -1
  7. package/dist/locales/de/constants.js +1 -1
  8. package/dist/locales/en/constants.js +1 -1
  9. package/dist/locales/en/parsers/ENRelativeDateFormatParser.js +3 -3
  10. package/dist/locales/en/parsers/ENTimeUnitAgoFormatParser.js +1 -1
  11. package/dist/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.js +1 -1
  12. package/dist/locales/en/parsers/ENTimeUnitLaterFormatParser.js +1 -1
  13. package/dist/locales/en/parsers/ENTimeUnitWithinFormatParser.js +1 -1
  14. package/dist/locales/fr/constants.js +1 -1
  15. package/dist/locales/fr/parsers/FRTimeUnitAgoFormatParser.js +1 -1
  16. package/dist/locales/fr/parsers/FRTimeUnitRelativeFormatParser.js +1 -1
  17. package/dist/locales/fr/parsers/FRTimeUnitWithinFormatParser.js +1 -1
  18. package/dist/locales/nl/parsers/NLRelativeDateFormatParser.js +3 -3
  19. package/dist/locales/nl/parsers/NLTimeUnitAgoFormatParser.js +1 -1
  20. package/dist/locales/nl/parsers/NLTimeUnitCasualRelativeFormatParser.js +1 -1
  21. package/dist/locales/nl/parsers/NLTimeUnitLaterFormatParser.js +1 -1
  22. package/dist/locales/nl/parsers/NLTimeUnitWithinFormatParser.js +1 -1
  23. package/dist/locales/zh/hans/constants.d.ts +27 -0
  24. package/dist/locales/zh/hans/constants.js +51 -0
  25. package/dist/locales/zh/hans/index.d.ts +9 -0
  26. package/dist/locales/zh/hans/index.js +49 -0
  27. package/dist/locales/zh/hans/parsers/ZHHansCasualDateParser.d.ts +7 -0
  28. package/dist/locales/zh/hans/parsers/ZHHansCasualDateParser.js +138 -0
  29. package/dist/locales/zh/hans/parsers/ZHHansDateParser.d.ts +6 -0
  30. package/dist/locales/zh/hans/parsers/ZHHansDateParser.js +72 -0
  31. package/dist/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.d.ts +6 -0
  32. package/dist/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.js +78 -0
  33. package/dist/locales/zh/hans/parsers/ZHHansRelationWeekdayParser.d.ts +7 -0
  34. package/dist/locales/zh/hans/parsers/ZHHansRelationWeekdayParser.js +70 -0
  35. package/dist/locales/zh/hans/parsers/ZHHansTimeExpressionParser.d.ts +6 -0
  36. package/dist/locales/zh/hans/parsers/ZHHansTimeExpressionParser.js +438 -0
  37. package/dist/locales/zh/hans/parsers/ZHHansWeekdayParser.d.ts +7 -0
  38. package/dist/locales/zh/hans/parsers/ZHHansWeekdayParser.js +46 -0
  39. package/dist/locales/zh/hans/refiners/ZHHansMergeDateRangeRefiner.d.ts +4 -0
  40. package/dist/locales/zh/hans/refiners/ZHHansMergeDateRangeRefiner.js +12 -0
  41. package/dist/locales/zh/hans/refiners/ZHHansMergeDateTimeRefiner.d.ts +4 -0
  42. package/dist/locales/zh/hans/refiners/ZHHansMergeDateTimeRefiner.js +12 -0
  43. package/dist/locales/zh/hant/constants.d.ts +28 -0
  44. package/dist/locales/zh/hant/constants.js +52 -0
  45. package/dist/locales/zh/hant/index.d.ts +9 -0
  46. package/dist/locales/zh/hant/index.js +49 -0
  47. package/dist/locales/zh/hant/parsers/ZHHantCasualDateParser.d.ts +7 -0
  48. package/dist/locales/zh/hant/parsers/ZHHantCasualDateParser.js +138 -0
  49. package/dist/locales/zh/hant/parsers/ZHHantDateParser.d.ts +6 -0
  50. package/dist/locales/zh/hant/parsers/ZHHantDateParser.js +64 -0
  51. package/dist/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.d.ts +6 -0
  52. package/dist/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.js +78 -0
  53. package/dist/locales/zh/hant/parsers/ZHHantRelationWeekdayParser.d.ts +7 -0
  54. package/dist/locales/zh/hant/parsers/ZHHantRelationWeekdayParser.js +70 -0
  55. package/dist/locales/zh/hant/parsers/ZHHantTimeExpressionParser.d.ts +6 -0
  56. package/dist/locales/zh/hant/parsers/ZHHantTimeExpressionParser.js +438 -0
  57. package/dist/locales/zh/hant/parsers/ZHHantWeekdayParser.d.ts +7 -0
  58. package/dist/locales/zh/hant/parsers/ZHHantWeekdayParser.js +46 -0
  59. package/dist/locales/zh/hant/refiners/ZHHantMergeDateRangeRefiner.d.ts +4 -0
  60. package/dist/locales/zh/hant/refiners/ZHHantMergeDateRangeRefiner.js +12 -0
  61. package/dist/locales/zh/hant/refiners/ZHHantMergeDateTimeRefiner.d.ts +4 -0
  62. package/dist/locales/zh/hant/refiners/ZHHantMergeDateTimeRefiner.js +12 -0
  63. package/dist/locales/zh/index.d.ts +2 -0
  64. package/dist/locales/zh/index.js +16 -0
  65. package/dist/results.d.ts +2 -2
  66. package/dist/results.js +18 -12
  67. package/dist/timezone.d.ts +1 -1
  68. package/dist/timezone.js +3 -0
  69. package/dist/utils/dayjs.js +7 -0
  70. package/package.json +1 -1
  71. package/src/common/casualReferences.ts +3 -1
  72. package/src/common/parsers/AbstractParserWithWordBoundary.ts +1 -1
  73. package/src/common/refiners/ExtractTimezoneAbbrRefiner.ts +8 -0
  74. package/src/index.ts +2 -1
  75. package/src/locales/de/constants.ts +1 -1
  76. package/src/locales/en/constants.ts +1 -1
  77. package/src/locales/en/parsers/ENMonthNameLittleEndianParser.ts +0 -2
  78. package/src/locales/en/parsers/ENRelativeDateFormatParser.ts +3 -3
  79. package/src/locales/en/parsers/ENTimeUnitAgoFormatParser.ts +1 -1
  80. package/src/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.ts +1 -1
  81. package/src/locales/en/parsers/ENTimeUnitLaterFormatParser.ts +1 -1
  82. package/src/locales/en/parsers/ENTimeUnitWithinFormatParser.ts +1 -1
  83. package/src/locales/fr/constants.ts +1 -1
  84. package/src/locales/fr/parsers/FRTimeUnitAgoFormatParser.ts +1 -1
  85. package/src/locales/fr/parsers/FRTimeUnitRelativeFormatParser.ts +1 -1
  86. package/src/locales/fr/parsers/FRTimeUnitWithinFormatParser.ts +1 -1
  87. package/src/locales/nl/parsers/NLRelativeDateFormatParser.ts +3 -3
  88. package/src/locales/nl/parsers/NLTimeUnitAgoFormatParser.ts +1 -1
  89. package/src/locales/nl/parsers/NLTimeUnitCasualRelativeFormatParser.ts +1 -1
  90. package/src/locales/nl/parsers/NLTimeUnitLaterFormatParser.ts +1 -1
  91. package/src/locales/nl/parsers/NLTimeUnitWithinFormatParser.ts +1 -1
  92. package/src/locales/zh/hans/constants.ts +52 -0
  93. package/src/locales/zh/hans/index.ts +62 -0
  94. package/src/locales/zh/hans/parsers/ZHHansCasualDateParser.ts +128 -0
  95. package/src/locales/zh/hans/parsers/ZHHansDateParser.ts +75 -0
  96. package/src/locales/zh/hans/parsers/ZHHansDeadlineFormatParser.ts +81 -0
  97. package/src/locales/zh/hans/parsers/ZHHansRelationWeekdayParser.ts +69 -0
  98. package/src/locales/zh/hans/parsers/ZHHansTimeExpressionParser.ts +424 -0
  99. package/src/locales/zh/hans/parsers/ZHHansWeekdayParser.ts +46 -0
  100. package/src/locales/zh/hans/refiners/ZHHansMergeDateRangeRefiner.ts +7 -0
  101. package/src/locales/zh/hans/refiners/ZHHansMergeDateTimeRefiner.ts +7 -0
  102. package/src/locales/zh/hant/constants.ts +53 -0
  103. package/src/locales/zh/hant/index.ts +63 -0
  104. package/src/locales/zh/hant/parsers/ZHHantCasualDateParser.ts +128 -0
  105. package/src/locales/zh/hant/parsers/ZHHantDateParser.ts +68 -0
  106. package/src/locales/zh/hant/parsers/ZHHantDeadlineFormatParser.ts +81 -0
  107. package/src/locales/zh/hant/parsers/ZHHantRelationWeekdayParser.ts +69 -0
  108. package/src/locales/zh/hant/parsers/ZHHantTimeExpressionParser.ts +424 -0
  109. package/src/locales/zh/hant/parsers/ZHHantWeekdayParser.ts +46 -0
  110. package/src/locales/zh/hant/refiners/ZHHantMergeDateRangeRefiner.ts +7 -0
  111. package/src/locales/zh/hant/refiners/ZHHantMergeDateTimeRefiner.ts +7 -0
  112. package/src/locales/zh/index.ts +2 -0
  113. package/src/results.ts +22 -12
  114. package/src/timezone.ts +5 -1
  115. package/src/utils/dayjs.ts +6 -0
  116. package/test/en/en_casual.test.ts +11 -0
  117. package/test/en/en_month.test.ts +13 -0
  118. package/test/en/en_relative.test.ts +8 -0
  119. package/test/en/en_time_units_ago.test.ts +16 -0
  120. package/test/en/en_time_units_later.test.ts +6 -0
  121. package/test/en/en_timezone_exp.test.ts +85 -10
  122. package/test/en/negative_cases.test.ts +2 -0
  123. package/test/test_util.ts +5 -2
  124. package/test/zh/zh.test.ts +18 -0
  125. package/test/zh/zh_hans_casual.test.ts +228 -0
  126. package/test/zh/zh_hans_date.test.ts +102 -0
  127. package/test/zh/zh_hans_deadline.test.ts +136 -0
  128. package/test/zh/zh_hans_time_exp.test.ts +182 -0
  129. package/test/zh/zh_hans_weekday.test.ts +132 -0
  130. package/test/zh/zh_hant_casual.test.ts +246 -0
  131. package/test/zh/zh_hant_date.test.ts +102 -0
  132. package/test/zh/zh_hant_deadline.test.ts +136 -0
  133. package/test/zh/zh_hant_time_exp.test.ts +182 -0
  134. 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 "./parsers/ZHHantCasualDateParser";
11
+ import ZHHantDateParser from "./parsers/ZHHantDateParser";
12
+ import ZHHantDeadlineFormatParser from "./parsers/ZHHantDeadlineFormatParser";
13
+ import ZHHantRelationWeekdayParser from "./parsers/ZHHantRelationWeekdayParser";
14
+ import ZHHantTimeExpressionParser from "./parsers/ZHHantTimeExpressionParser";
15
+ import ZHHantWeekdayParser from "./parsers/ZHHantWeekdayParser";
16
+ import ZHHantMergeDateRangeRefiner from "./refiners/ZHHantMergeDateRangeRefiner";
17
+ import ZHHantMergeDateTimeRefiner from "./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
+ }
@@ -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
+ }
@@ -0,0 +1,81 @@
1
+ import dayjs from "dayjs";
2
+ import { ParsingContext } from "../../../../chrono";
3
+ import { AbstractParserWithWordBoundaryChecking } from "../../../../common/parsers/AbstractParserWithWordBoundary";
4
+ import { NUMBER, zhStringToNumber } from "../constants";
5
+
6
+ const PATTERN = new RegExp(
7
+ "(\\d+|[" +
8
+ Object.keys(NUMBER).join("") +
9
+ "]+|半|幾)(?:\\s*)" +
10
+ "(?:個)?" +
11
+ "(秒(?:鐘)?|分鐘|小時|鐘|日|天|星期|禮拜|月|年)" +
12
+ "(?:(?:之|過)?後|(?:之)?內)",
13
+ "i"
14
+ );
15
+
16
+ const NUMBER_GROUP = 1;
17
+ const UNIT_GROUP = 2;
18
+
19
+ export default class ZHHantDeadlineFormatParser extends AbstractParserWithWordBoundaryChecking {
20
+ innerPattern(): RegExp {
21
+ return PATTERN;
22
+ }
23
+
24
+ innerExtract(context: ParsingContext, match: RegExpMatchArray) {
25
+ const result = context.createParsingResult(match.index, match[0]);
26
+
27
+ let number = parseInt(match[NUMBER_GROUP]);
28
+ if (isNaN(number)) {
29
+ number = zhStringToNumber(match[NUMBER_GROUP]);
30
+ }
31
+
32
+ if (isNaN(number)) {
33
+ const string = match[NUMBER_GROUP];
34
+ if (string === "幾") {
35
+ number = 3;
36
+ } else if (string === "半") {
37
+ number = 0.5;
38
+ } else {
39
+ //just in case
40
+ return null;
41
+ }
42
+ }
43
+
44
+ let date = dayjs(context.refDate);
45
+ const unit = match[UNIT_GROUP];
46
+ const unitAbbr = unit[0];
47
+
48
+ if (unitAbbr.match(/[日天星禮月年]/)) {
49
+ if (unitAbbr == "日" || unitAbbr == "天") {
50
+ date = date.add(number, "d");
51
+ } else if (unitAbbr == "星" || unitAbbr == "禮") {
52
+ date = date.add(number * 7, "d");
53
+ } else if (unitAbbr == "月") {
54
+ date = date.add(number, "month");
55
+ } else if (unitAbbr == "年") {
56
+ date = date.add(number, "year");
57
+ }
58
+
59
+ result.start.assign("year", date.year());
60
+ result.start.assign("month", date.month() + 1);
61
+ result.start.assign("day", date.date());
62
+ return result;
63
+ }
64
+
65
+ if (unitAbbr == "秒") {
66
+ date = date.add(number, "second");
67
+ } else if (unitAbbr == "分") {
68
+ date = date.add(number, "minute");
69
+ } else if (unitAbbr == "小" || unitAbbr == "鐘") {
70
+ date = date.add(number, "hour");
71
+ }
72
+
73
+ result.start.imply("year", date.year());
74
+ result.start.imply("month", date.month() + 1);
75
+ result.start.imply("day", date.date());
76
+ result.start.assign("hour", date.hour());
77
+ result.start.assign("minute", date.minute());
78
+ result.start.assign("second", date.second());
79
+ return result;
80
+ }
81
+ }
@@ -0,0 +1,69 @@
1
+ import dayjs from "dayjs";
2
+ import { ParsingContext } from "../../../../chrono";
3
+ import { AbstractParserWithWordBoundaryChecking } from "../../../../common/parsers/AbstractParserWithWordBoundary";
4
+ import { ParsingResult } from "../../../../results";
5
+ import { WEEKDAY_OFFSET } from "../constants";
6
+
7
+ const PATTERN = new RegExp(
8
+ "(?<prefix>上|今|下|這|呢)(?:個)?(?:星期|禮拜|週)(?<weekday>" + Object.keys(WEEKDAY_OFFSET).join("|") + ")"
9
+ );
10
+
11
+ export default class ZHHantRelationWeekdayParser extends AbstractParserWithWordBoundaryChecking {
12
+ innerPattern(): RegExp {
13
+ return PATTERN;
14
+ }
15
+
16
+ innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingResult {
17
+ const result = context.createParsingResult(match.index, match[0]);
18
+
19
+ const dayOfWeek = match.groups.weekday;
20
+ const offset = WEEKDAY_OFFSET[dayOfWeek];
21
+ if (offset === undefined) return null;
22
+
23
+ let modifier = null;
24
+ const prefix = match.groups.prefix;
25
+
26
+ if (prefix == "上") {
27
+ modifier = "last";
28
+ } else if (prefix == "下") {
29
+ modifier = "next";
30
+ } else if (prefix == "今" || prefix == "這" || prefix == "呢") {
31
+ modifier = "this";
32
+ }
33
+
34
+ let startMoment = dayjs(context.refDate);
35
+ let startMomentFixed = false;
36
+ const refOffset = startMoment.day();
37
+
38
+ if (modifier == "last" || modifier == "past") {
39
+ startMoment = startMoment.day(offset - 7);
40
+ startMomentFixed = true;
41
+ } else if (modifier == "next") {
42
+ startMoment = startMoment.day(offset + 7);
43
+ startMomentFixed = true;
44
+ } else if (modifier == "this") {
45
+ startMoment = startMoment.day(offset);
46
+ } else {
47
+ if (Math.abs(offset - 7 - refOffset) < Math.abs(offset - refOffset)) {
48
+ startMoment = startMoment.day(offset - 7);
49
+ } else if (Math.abs(offset + 7 - refOffset) < Math.abs(offset - refOffset)) {
50
+ startMoment = startMoment.day(offset + 7);
51
+ } else {
52
+ startMoment = startMoment.day(offset);
53
+ }
54
+ }
55
+
56
+ result.start.assign("weekday", offset);
57
+ if (startMomentFixed) {
58
+ result.start.assign("day", startMoment.date());
59
+ result.start.assign("month", startMoment.month() + 1);
60
+ result.start.assign("year", startMoment.year());
61
+ } else {
62
+ result.start.imply("day", startMoment.date());
63
+ result.start.imply("month", startMoment.month() + 1);
64
+ result.start.imply("year", startMoment.year());
65
+ }
66
+
67
+ return result;
68
+ }
69
+ }