chrono-node 2.7.8 → 2.8.0

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 (182) hide show
  1. package/dist/cjs/common/casualReferences.js +8 -10
  2. package/dist/cjs/common/casualReferences.js.map +1 -1
  3. package/dist/cjs/common/refiners/ForwardDateRefiner.js +33 -12
  4. package/dist/cjs/common/refiners/ForwardDateRefiner.js.map +1 -1
  5. package/dist/cjs/locales/en/parsers/ENCasualDateParser.js +4 -1
  6. package/dist/cjs/locales/en/parsers/ENCasualDateParser.js.map +1 -1
  7. package/dist/cjs/locales/it/constants.d.ts +28 -0
  8. package/dist/cjs/locales/it/constants.js +165 -0
  9. package/dist/cjs/locales/it/constants.js.map +1 -0
  10. package/dist/cjs/locales/it/index.d.ts +9 -0
  11. package/dist/cjs/locales/it/index.js +66 -0
  12. package/dist/cjs/locales/it/index.js.map +1 -0
  13. package/dist/cjs/locales/it/parsers/ITCasualDateParser.d.ts +7 -0
  14. package/dist/cjs/locales/it/parsers/ITCasualDateParser.js +65 -0
  15. package/dist/cjs/locales/it/parsers/ITCasualDateParser.js.map +1 -0
  16. package/dist/cjs/locales/it/parsers/ITCasualTimeParser.d.ts +6 -0
  17. package/dist/cjs/locales/it/parsers/ITCasualTimeParser.js +47 -0
  18. package/dist/cjs/locales/it/parsers/ITCasualTimeParser.js.map +1 -0
  19. package/dist/cjs/locales/it/parsers/ITCasualYearMonthDayParser.d.ts +10 -0
  20. package/dist/cjs/locales/it/parsers/ITCasualYearMonthDayParser.js +35 -0
  21. package/dist/cjs/locales/it/parsers/ITCasualYearMonthDayParser.js.map +1 -0
  22. package/dist/cjs/locales/it/parsers/ITMonthNameLittleEndianParser.d.ts +7 -0
  23. package/dist/cjs/locales/it/parsers/ITMonthNameLittleEndianParser.js +57 -0
  24. package/dist/cjs/locales/it/parsers/ITMonthNameLittleEndianParser.js.map +1 -0
  25. package/dist/cjs/locales/it/parsers/ITMonthNameMiddleEndianParser.d.ts +6 -0
  26. package/dist/cjs/locales/it/parsers/ITMonthNameMiddleEndianParser.js +59 -0
  27. package/dist/cjs/locales/it/parsers/ITMonthNameMiddleEndianParser.js.map +1 -0
  28. package/dist/cjs/locales/it/parsers/ITMonthNameParser.d.ts +6 -0
  29. package/dist/cjs/locales/it/parsers/ITMonthNameParser.js +43 -0
  30. package/dist/cjs/locales/it/parsers/ITMonthNameParser.js.map +1 -0
  31. package/dist/cjs/locales/it/parsers/ITRelativeDateFormatParser.d.ts +7 -0
  32. package/dist/cjs/locales/it/parsers/ITRelativeDateFormatParser.js +57 -0
  33. package/dist/cjs/locales/it/parsers/ITRelativeDateFormatParser.js.map +1 -0
  34. package/dist/cjs/locales/it/parsers/ITSlashMonthFormatParser.d.ts +7 -0
  35. package/dist/cjs/locales/it/parsers/ITSlashMonthFormatParser.js +18 -0
  36. package/dist/cjs/locales/it/parsers/ITSlashMonthFormatParser.js.map +1 -0
  37. package/dist/cjs/locales/it/parsers/ITTimeExpressionParser.d.ts +10 -0
  38. package/dist/cjs/locales/it/parsers/ITTimeExpressionParser.js +50 -0
  39. package/dist/cjs/locales/it/parsers/ITTimeExpressionParser.js.map +1 -0
  40. package/dist/cjs/locales/it/parsers/ITTimeUnitAgoFormatParser.d.ts +9 -0
  41. package/dist/cjs/locales/it/parsers/ITTimeUnitAgoFormatParser.js +24 -0
  42. package/dist/cjs/locales/it/parsers/ITTimeUnitAgoFormatParser.js.map +1 -0
  43. package/dist/cjs/locales/it/parsers/ITTimeUnitCasualRelativeFormatParser.d.ts +7 -0
  44. package/dist/cjs/locales/it/parsers/ITTimeUnitCasualRelativeFormatParser.js +26 -0
  45. package/dist/cjs/locales/it/parsers/ITTimeUnitCasualRelativeFormatParser.js.map +1 -0
  46. package/dist/cjs/locales/it/parsers/ITTimeUnitLaterFormatParser.d.ts +9 -0
  47. package/dist/cjs/locales/it/parsers/ITTimeUnitLaterFormatParser.js +23 -0
  48. package/dist/cjs/locales/it/parsers/ITTimeUnitLaterFormatParser.js.map +1 -0
  49. package/dist/cjs/locales/it/parsers/ITTimeUnitWithinFormatParser.d.ts +7 -0
  50. package/dist/cjs/locales/it/parsers/ITTimeUnitWithinFormatParser.js +19 -0
  51. package/dist/cjs/locales/it/parsers/ITTimeUnitWithinFormatParser.js.map +1 -0
  52. package/dist/cjs/locales/it/parsers/ITWeekdayParser.d.ts +7 -0
  53. package/dist/cjs/locales/it/parsers/ITWeekdayParser.js +43 -0
  54. package/dist/cjs/locales/it/parsers/ITWeekdayParser.js.map +1 -0
  55. package/dist/cjs/locales/it/refiners/ITMergeDateRangeRefiner.d.ts +4 -0
  56. package/dist/cjs/locales/it/refiners/ITMergeDateRangeRefiner.js +13 -0
  57. package/dist/cjs/locales/it/refiners/ITMergeDateRangeRefiner.js.map +1 -0
  58. package/dist/cjs/locales/it/refiners/ITMergeDateTimeRefiner.d.ts +4 -0
  59. package/dist/cjs/locales/it/refiners/ITMergeDateTimeRefiner.js +13 -0
  60. package/dist/cjs/locales/it/refiners/ITMergeDateTimeRefiner.js.map +1 -0
  61. package/dist/cjs/locales/it/refiners/ITMergeRelativeDateRefiner.d.ts +7 -0
  62. package/dist/cjs/locales/it/refiners/ITMergeRelativeDateRefiner.js +36 -0
  63. package/dist/cjs/locales/it/refiners/ITMergeRelativeDateRefiner.js.map +1 -0
  64. package/dist/cjs/locales/ja/parsers/JPCasualDateParser.js +4 -4
  65. package/dist/cjs/locales/ja/refiners/JPMergeDateRangeRefiner.js +1 -1
  66. package/dist/cjs/locales/ja/refiners/JPMergeDateRangeRefiner.js.map +1 -1
  67. package/dist/cjs/results.d.ts +1 -0
  68. package/dist/cjs/results.js +18 -13
  69. package/dist/cjs/results.js.map +1 -1
  70. package/dist/cjs/utils/dates.d.ts +3 -0
  71. package/dist/cjs/utils/dates.js +17 -0
  72. package/dist/cjs/utils/dates.js.map +1 -0
  73. package/dist/cjs/utils/dayjs.js.map +1 -1
  74. package/dist/esm/common/casualReferences.js +8 -10
  75. package/dist/esm/common/casualReferences.js.map +1 -1
  76. package/dist/esm/common/refiners/ForwardDateRefiner.js +14 -12
  77. package/dist/esm/common/refiners/ForwardDateRefiner.js.map +1 -1
  78. package/dist/esm/locales/en/parsers/ENCasualDateParser.js +4 -1
  79. package/dist/esm/locales/en/parsers/ENCasualDateParser.js.map +1 -1
  80. package/dist/esm/locales/it/constants.d.ts +28 -0
  81. package/dist/esm/locales/it/constants.js +200 -0
  82. package/dist/esm/locales/it/constants.js.map +1 -0
  83. package/dist/esm/locales/it/index.d.ts +9 -0
  84. package/dist/esm/locales/it/index.js +56 -0
  85. package/dist/esm/locales/it/index.js.map +1 -0
  86. package/dist/esm/locales/it/parsers/ITCasualDateParser.d.ts +7 -0
  87. package/dist/esm/locales/it/parsers/ITCasualDateParser.js +40 -0
  88. package/dist/esm/locales/it/parsers/ITCasualDateParser.js.map +1 -0
  89. package/dist/esm/locales/it/parsers/ITCasualTimeParser.d.ts +6 -0
  90. package/dist/esm/locales/it/parsers/ITCasualTimeParser.js +41 -0
  91. package/dist/esm/locales/it/parsers/ITCasualTimeParser.js.map +1 -0
  92. package/dist/esm/locales/it/parsers/ITCasualYearMonthDayParser.d.ts +10 -0
  93. package/dist/esm/locales/it/parsers/ITCasualYearMonthDayParser.js +32 -0
  94. package/dist/esm/locales/it/parsers/ITCasualYearMonthDayParser.js.map +1 -0
  95. package/dist/esm/locales/it/parsers/ITMonthNameLittleEndianParser.d.ts +7 -0
  96. package/dist/esm/locales/it/parsers/ITMonthNameLittleEndianParser.js +54 -0
  97. package/dist/esm/locales/it/parsers/ITMonthNameLittleEndianParser.js.map +1 -0
  98. package/dist/esm/locales/it/parsers/ITMonthNameMiddleEndianParser.d.ts +6 -0
  99. package/dist/esm/locales/it/parsers/ITMonthNameMiddleEndianParser.js +56 -0
  100. package/dist/esm/locales/it/parsers/ITMonthNameMiddleEndianParser.js.map +1 -0
  101. package/dist/esm/locales/it/parsers/ITMonthNameParser.d.ts +6 -0
  102. package/dist/esm/locales/it/parsers/ITMonthNameParser.js +40 -0
  103. package/dist/esm/locales/it/parsers/ITMonthNameParser.js.map +1 -0
  104. package/dist/esm/locales/it/parsers/ITRelativeDateFormatParser.d.ts +7 -0
  105. package/dist/esm/locales/it/parsers/ITRelativeDateFormatParser.js +51 -0
  106. package/dist/esm/locales/it/parsers/ITRelativeDateFormatParser.js.map +1 -0
  107. package/dist/esm/locales/it/parsers/ITSlashMonthFormatParser.d.ts +7 -0
  108. package/dist/esm/locales/it/parsers/ITSlashMonthFormatParser.js +15 -0
  109. package/dist/esm/locales/it/parsers/ITSlashMonthFormatParser.js.map +1 -0
  110. package/dist/esm/locales/it/parsers/ITTimeExpressionParser.d.ts +10 -0
  111. package/dist/esm/locales/it/parsers/ITTimeExpressionParser.js +47 -0
  112. package/dist/esm/locales/it/parsers/ITTimeExpressionParser.js.map +1 -0
  113. package/dist/esm/locales/it/parsers/ITTimeUnitAgoFormatParser.d.ts +9 -0
  114. package/dist/esm/locales/it/parsers/ITTimeUnitAgoFormatParser.js +21 -0
  115. package/dist/esm/locales/it/parsers/ITTimeUnitAgoFormatParser.js.map +1 -0
  116. package/dist/esm/locales/it/parsers/ITTimeUnitCasualRelativeFormatParser.d.ts +7 -0
  117. package/dist/esm/locales/it/parsers/ITTimeUnitCasualRelativeFormatParser.js +23 -0
  118. package/dist/esm/locales/it/parsers/ITTimeUnitCasualRelativeFormatParser.js.map +1 -0
  119. package/dist/esm/locales/it/parsers/ITTimeUnitLaterFormatParser.d.ts +9 -0
  120. package/dist/esm/locales/it/parsers/ITTimeUnitLaterFormatParser.js +20 -0
  121. package/dist/esm/locales/it/parsers/ITTimeUnitLaterFormatParser.js.map +1 -0
  122. package/dist/esm/locales/it/parsers/ITTimeUnitWithinFormatParser.d.ts +7 -0
  123. package/dist/esm/locales/it/parsers/ITTimeUnitWithinFormatParser.js +16 -0
  124. package/dist/esm/locales/it/parsers/ITTimeUnitWithinFormatParser.js.map +1 -0
  125. package/dist/esm/locales/it/parsers/ITWeekdayParser.d.ts +7 -0
  126. package/dist/esm/locales/it/parsers/ITWeekdayParser.js +40 -0
  127. package/dist/esm/locales/it/parsers/ITWeekdayParser.js.map +1 -0
  128. package/dist/esm/locales/it/refiners/ITMergeDateRangeRefiner.d.ts +4 -0
  129. package/dist/esm/locales/it/refiners/ITMergeDateRangeRefiner.js +7 -0
  130. package/dist/esm/locales/it/refiners/ITMergeDateRangeRefiner.js.map +1 -0
  131. package/dist/esm/locales/it/refiners/ITMergeDateTimeRefiner.d.ts +4 -0
  132. package/dist/esm/locales/it/refiners/ITMergeDateTimeRefiner.js +7 -0
  133. package/dist/esm/locales/it/refiners/ITMergeDateTimeRefiner.js.map +1 -0
  134. package/dist/esm/locales/it/refiners/ITMergeRelativeDateRefiner.d.ts +7 -0
  135. package/dist/esm/locales/it/refiners/ITMergeRelativeDateRefiner.js +33 -0
  136. package/dist/esm/locales/it/refiners/ITMergeRelativeDateRefiner.js.map +1 -0
  137. package/dist/esm/locales/ja/parsers/JPCasualDateParser.js +4 -4
  138. package/dist/esm/locales/ja/refiners/JPMergeDateRangeRefiner.js +1 -1
  139. package/dist/esm/locales/ja/refiners/JPMergeDateRangeRefiner.js.map +1 -1
  140. package/dist/esm/results.d.ts +1 -0
  141. package/dist/esm/results.js +17 -13
  142. package/dist/esm/results.js.map +1 -1
  143. package/dist/esm/utils/dates.d.ts +3 -0
  144. package/dist/esm/utils/dates.js +12 -0
  145. package/dist/esm/utils/dates.js.map +1 -0
  146. package/dist/esm/utils/dayjs.js.map +1 -1
  147. package/package.json +1 -1
  148. package/src/common/casualReferences.ts +8 -10
  149. package/src/common/refiners/ForwardDateRefiner.ts +17 -11
  150. package/src/locales/en/parsers/ENCasualDateParser.ts +5 -1
  151. package/src/locales/it/constants.ts +230 -0
  152. package/src/locales/it/index.ts +99 -0
  153. package/src/locales/it/parsers/ITCasualDateParser.ts +53 -0
  154. package/src/locales/it/parsers/ITCasualTimeParser.ts +50 -0
  155. package/src/locales/it/parsers/ITCasualYearMonthDayParser.ts +49 -0
  156. package/src/locales/it/parsers/ITMonthNameLittleEndianParser.ts +69 -0
  157. package/src/locales/it/parsers/ITMonthNameMiddleEndianParser.ts +78 -0
  158. package/src/locales/it/parsers/ITMonthNameParser.ts +62 -0
  159. package/src/locales/it/parsers/ITRelativeDateFormatParser.ts +71 -0
  160. package/src/locales/it/parsers/ITSlashMonthFormatParser.ts +26 -0
  161. package/src/locales/it/parsers/ITTimeExpressionParser.ts +55 -0
  162. package/src/locales/it/parsers/ITTimeUnitAgoFormatParser.ts +25 -0
  163. package/src/locales/it/parsers/ITTimeUnitCasualRelativeFormatParser.ts +30 -0
  164. package/src/locales/it/parsers/ITTimeUnitLaterFormatParser.ts +27 -0
  165. package/src/locales/it/parsers/ITTimeUnitWithinFormatParser.ts +26 -0
  166. package/src/locales/it/parsers/ITWeekdayParser.ts +47 -0
  167. package/src/locales/it/refiners/ITMergeDateRangeRefiner.ts +17 -0
  168. package/src/locales/it/refiners/ITMergeDateTimeRefiner.ts +13 -0
  169. package/src/locales/it/refiners/ITMergeRelativeDateRefiner.ts +58 -0
  170. package/src/locales/ja/parsers/JPCasualDateParser.ts +4 -4
  171. package/src/locales/ja/refiners/JPMergeDateRangeRefiner.ts +1 -1
  172. package/src/results.ts +18 -13
  173. package/src/utils/dates.ts +24 -0
  174. package/src/utils/dayjs.ts +6 -0
  175. package/test/en/en_casual.test.ts +4 -1
  176. package/test/en/en_relative.test.ts +126 -39
  177. package/test/en/en_time_exp.test.ts +27 -18
  178. package/test/ja/ja_casual.test.ts +8 -0
  179. package/test/ja/ja_standard.test.ts +19 -0
  180. package/test/nl/nl_relative.test.ts +33 -17
  181. package/test/result.test.ts +24 -0
  182. package/test/system_timezone.test.ts +20 -4
@@ -0,0 +1,49 @@
1
+ import { ParsingContext } from "../../../chrono";
2
+ import { MONTH_DICTIONARY } from "../constants";
3
+ import { matchAnyPattern } from "../../../utils/pattern";
4
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
5
+
6
+ /*
7
+ Date format with slash "/" between numbers like ENSlashDateFormatParser,
8
+ but this parser expect year before month and date.
9
+ - YYYY/MM/DD
10
+ - YYYY-MM-DD
11
+ - YYYY.MM.DD
12
+ */
13
+ const PATTERN = new RegExp(
14
+ `([0-9]{4})[\\.\\/\\s]` +
15
+ `(?:(${matchAnyPattern(MONTH_DICTIONARY)})|([0-9]{1,2}))[\\.\\/\\s]` +
16
+ `([0-9]{1,2})` +
17
+ "(?=\\W|$)",
18
+ "i"
19
+ );
20
+
21
+ const YEAR_NUMBER_GROUP = 1;
22
+ const MONTH_NAME_GROUP = 2;
23
+ const MONTH_NUMBER_GROUP = 3;
24
+ const DATE_NUMBER_GROUP = 4;
25
+
26
+ export default class ENCasualYearMonthDayParser extends AbstractParserWithWordBoundaryChecking {
27
+ innerPattern(): RegExp {
28
+ return PATTERN;
29
+ }
30
+
31
+ innerExtract(context: ParsingContext, match: RegExpMatchArray) {
32
+ const month = match[MONTH_NUMBER_GROUP]
33
+ ? parseInt(match[MONTH_NUMBER_GROUP])
34
+ : MONTH_DICTIONARY[match[MONTH_NAME_GROUP].toLowerCase()];
35
+
36
+ if (month < 1 || month > 12) {
37
+ return null;
38
+ }
39
+
40
+ const year = parseInt(match[YEAR_NUMBER_GROUP]);
41
+ const day = parseInt(match[DATE_NUMBER_GROUP]);
42
+
43
+ return {
44
+ day: day,
45
+ month: month,
46
+ year: year,
47
+ };
48
+ }
49
+ }
@@ -0,0 +1,69 @@
1
+ import { ParsingContext } from "../../../chrono";
2
+ import { ParsingResult } from "../../../results";
3
+ import { findYearClosestToRef } from "../../../calculation/years";
4
+ import { MONTH_DICTIONARY } from "../constants";
5
+ import { YEAR_PATTERN, parseYear } from "../constants";
6
+ import { ORDINAL_NUMBER_PATTERN, parseOrdinalNumberPattern } from "../constants";
7
+ import { matchAnyPattern } from "../../../utils/pattern";
8
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
9
+
10
+ // prettier-ignore
11
+ const PATTERN = new RegExp(
12
+ `(?:on\\s{0,3})?` +
13
+ `(${ORDINAL_NUMBER_PATTERN})` +
14
+ `(?:` +
15
+ `\\s{0,3}(?:al|\\-|\\–|fino|alle|allo)?\\s{0,3}` +
16
+ `(${ORDINAL_NUMBER_PATTERN})` +
17
+ ")?" +
18
+ `(?:-|/|\\s{0,3}(?:dal)?\\s{0,3})` +
19
+ `(${matchAnyPattern(MONTH_DICTIONARY)})` +
20
+ "(?:" +
21
+ `(?:-|/|,?\\s{0,3})` +
22
+ `(${YEAR_PATTERN}(?![^\\s]\\d))` +
23
+ ")?" +
24
+ "(?=\\W|$)",
25
+ "i"
26
+ );
27
+
28
+ const DATE_GROUP = 1;
29
+ const DATE_TO_GROUP = 2;
30
+ const MONTH_NAME_GROUP = 3;
31
+ const YEAR_GROUP = 4;
32
+
33
+ export default class ENMonthNameLittleEndianParser extends AbstractParserWithWordBoundaryChecking {
34
+ innerPattern(): RegExp {
35
+ return PATTERN;
36
+ }
37
+
38
+ innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingResult {
39
+ const result = context.createParsingResult(match.index, match[0]);
40
+
41
+ const month = MONTH_DICTIONARY[match[MONTH_NAME_GROUP].toLowerCase()];
42
+ const day = parseOrdinalNumberPattern(match[DATE_GROUP]);
43
+ if (day > 31) {
44
+ // e.g. "[96 Aug]" => "9[6 Aug]", we need to shift away from the next number
45
+ match.index = match.index + match[DATE_GROUP].length;
46
+ return null;
47
+ }
48
+
49
+ result.start.assign("month", month);
50
+ result.start.assign("day", day);
51
+
52
+ if (match[YEAR_GROUP]) {
53
+ const yearNumber = parseYear(match[YEAR_GROUP]);
54
+ result.start.assign("year", yearNumber);
55
+ } else {
56
+ const year = findYearClosestToRef(context.refDate, day, month);
57
+ result.start.imply("year", year);
58
+ }
59
+
60
+ if (match[DATE_TO_GROUP]) {
61
+ const endDate = parseOrdinalNumberPattern(match[DATE_TO_GROUP]);
62
+
63
+ result.end = result.start.clone();
64
+ result.end.assign("day", endDate);
65
+ }
66
+
67
+ return result;
68
+ }
69
+ }
@@ -0,0 +1,78 @@
1
+ import { ParsingContext } from "../../../chrono";
2
+ import { findYearClosestToRef } from "../../../calculation/years";
3
+ import { MONTH_DICTIONARY } from "../constants";
4
+ import { ORDINAL_NUMBER_PATTERN, parseOrdinalNumberPattern } from "../constants";
5
+ import { YEAR_PATTERN, parseYear } from "../constants";
6
+ import { matchAnyPattern } from "../../../utils/pattern";
7
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
8
+
9
+ const PATTERN = new RegExp(
10
+ `(${matchAnyPattern(MONTH_DICTIONARY)})` +
11
+ "(?:-|/|\\s*,?\\s*)" +
12
+ `(${ORDINAL_NUMBER_PATTERN})(?!\\s*(?:am|pm))\\s*` +
13
+ "(?:" +
14
+ "(?:al|\\-|\\alle|\\del|\\s)\\s*" +
15
+ `(${ORDINAL_NUMBER_PATTERN})\\s*` +
16
+ ")?" +
17
+ "(?:" +
18
+ "(?:-|/|\\s*,?\\s*)" +
19
+ `(${YEAR_PATTERN})` +
20
+ ")?" +
21
+ "(?=\\W|$)(?!\\:\\d)",
22
+ "i"
23
+ );
24
+
25
+ const MONTH_NAME_GROUP = 1;
26
+ const DATE_GROUP = 2;
27
+ const DATE_TO_GROUP = 3;
28
+ const YEAR_GROUP = 4;
29
+
30
+ /**
31
+ * The parser for parsing US's date format that begin with month's name.
32
+ * - January 13
33
+ * - January 13, 2012
34
+ * - January 13 - 15, 2012
35
+ * Note: Watch out for:
36
+ * - January 12:00
37
+ * - January 12.44
38
+ * - January 1222344
39
+ */
40
+ export default class ENMonthNameMiddleEndianParser extends AbstractParserWithWordBoundaryChecking {
41
+ innerPattern(): RegExp {
42
+ return PATTERN;
43
+ }
44
+
45
+ innerExtract(context: ParsingContext, match: RegExpMatchArray) {
46
+ const month = MONTH_DICTIONARY[match[MONTH_NAME_GROUP].toLowerCase()];
47
+ const day = parseOrdinalNumberPattern(match[DATE_GROUP]);
48
+ if (day > 31) {
49
+ return null;
50
+ }
51
+
52
+ const components = context.createParsingComponents({
53
+ day: day,
54
+ month: month,
55
+ });
56
+
57
+ if (match[YEAR_GROUP]) {
58
+ const year = parseYear(match[YEAR_GROUP]);
59
+ components.assign("year", year);
60
+ } else {
61
+ const year = findYearClosestToRef(context.refDate, day, month);
62
+ components.imply("year", year);
63
+ }
64
+
65
+ if (!match[DATE_TO_GROUP]) {
66
+ return components;
67
+ }
68
+
69
+ // Text can be 'range' value. Such as 'January 12 - 13, 2012'
70
+ const endDate = parseOrdinalNumberPattern(match[DATE_TO_GROUP]);
71
+ const result = context.createParsingResult(match.index, match[0]);
72
+ result.start = components;
73
+ result.end = components.clone();
74
+ result.end.assign("day", endDate);
75
+
76
+ return result;
77
+ }
78
+ }
@@ -0,0 +1,62 @@
1
+ import { FULL_MONTH_NAME_DICTIONARY, MONTH_DICTIONARY } from "../constants";
2
+ import { ParsingContext } from "../../../chrono";
3
+ import { findYearClosestToRef } from "../../../calculation/years";
4
+ import { matchAnyPattern } from "../../../utils/pattern";
5
+ import { YEAR_PATTERN, parseYear } from "../constants";
6
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
7
+
8
+ const PATTERN = new RegExp(
9
+ `((?:in)\\s*)?` +
10
+ `(${matchAnyPattern(MONTH_DICTIONARY)})` +
11
+ `\\s*` +
12
+ `(?:` +
13
+ `[,-]?\\s*(${YEAR_PATTERN})?` +
14
+ ")?" +
15
+ "(?=[^\\s\\w]|\\s+[^0-9]|\\s+$|$)",
16
+ "i"
17
+ );
18
+
19
+ const PREFIX_GROUP = 1;
20
+ const MONTH_NAME_GROUP = 2;
21
+ const YEAR_GROUP = 3;
22
+
23
+ /**
24
+ * The parser for parsing month name and year.
25
+ * - January, 2012
26
+ * - January 2012
27
+ * - January
28
+ * (in) Jan
29
+ */
30
+ export default class ENMonthNameParser extends AbstractParserWithWordBoundaryChecking {
31
+ innerPattern(): RegExp {
32
+ return PATTERN;
33
+ }
34
+
35
+ innerExtract(context: ParsingContext, match: RegExpMatchArray) {
36
+ const monthName = match[MONTH_NAME_GROUP].toLowerCase();
37
+
38
+ // skip some unlikely words "jan", "mar", ..
39
+ if (match[0].length <= 3 && !FULL_MONTH_NAME_DICTIONARY[monthName]) {
40
+ return null;
41
+ }
42
+
43
+ const result = context.createParsingResult(
44
+ match.index + (match[PREFIX_GROUP] || "").length,
45
+ match.index + match[0].length
46
+ );
47
+ result.start.imply("day", 1);
48
+
49
+ const month = MONTH_DICTIONARY[monthName];
50
+ result.start.assign("month", month);
51
+
52
+ if (match[YEAR_GROUP]) {
53
+ const year = parseYear(match[YEAR_GROUP]);
54
+ result.start.assign("year", year);
55
+ } else {
56
+ const year = findYearClosestToRef(context.refDate, 1, month);
57
+ result.start.imply("year", year);
58
+ }
59
+
60
+ return result;
61
+ }
62
+ }
@@ -0,0 +1,71 @@
1
+ import { TIME_UNIT_DICTIONARY } from "../constants";
2
+ import { ParsingContext } from "../../../chrono";
3
+ import { ParsingComponents } from "../../../results";
4
+ import dayjs from "dayjs";
5
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
6
+ import { matchAnyPattern } from "../../../utils/pattern";
7
+
8
+ const PATTERN = new RegExp(
9
+ `(questo|ultimo|scorso|prossimo|dopo\\s*questo|questa|ultima|scorsa|prossima\\s*questa)\\s*(${matchAnyPattern(
10
+ TIME_UNIT_DICTIONARY
11
+ )})(?=\\s*)` + "(?=\\W|$)",
12
+ "i"
13
+ );
14
+
15
+ const MODIFIER_WORD_GROUP = 1;
16
+ const RELATIVE_WORD_GROUP = 2;
17
+
18
+ export default class ENRelativeDateFormatParser extends AbstractParserWithWordBoundaryChecking {
19
+ innerPattern(): RegExp {
20
+ return PATTERN;
21
+ }
22
+
23
+ innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
24
+ const modifier = match[MODIFIER_WORD_GROUP].toLowerCase();
25
+ const unitWord = match[RELATIVE_WORD_GROUP].toLowerCase();
26
+ const timeunit = TIME_UNIT_DICTIONARY[unitWord];
27
+
28
+ if (modifier == "prossimo" || modifier.startsWith("dopo")) {
29
+ const timeUnits = {};
30
+ timeUnits[timeunit] = 1;
31
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
32
+ }
33
+
34
+ if (modifier == "prima" || modifier == "precedente") {
35
+ const timeUnits = {};
36
+ timeUnits[timeunit] = -1;
37
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
38
+ }
39
+
40
+ const components = context.createParsingComponents();
41
+ let date = dayjs(context.reference.instant);
42
+
43
+ // This week
44
+ if (unitWord.match(/settimana/i)) {
45
+ date = date.add(-date.get("d"), "d");
46
+ components.imply("day", date.date());
47
+ components.imply("month", date.month() + 1);
48
+ components.imply("year", date.year());
49
+ }
50
+
51
+ // This month
52
+ else if (unitWord.match(/mese/i)) {
53
+ date = date.add(-date.date() + 1, "d");
54
+ components.imply("day", date.date());
55
+ components.assign("year", date.year());
56
+ components.assign("month", date.month() + 1);
57
+ }
58
+
59
+ // This year
60
+ else if (unitWord.match(/anno/i)) {
61
+ date = date.add(-date.date() + 1, "d");
62
+ date = date.add(-date.month(), "month");
63
+
64
+ components.imply("day", date.date());
65
+ components.imply("month", date.month() + 1);
66
+ components.assign("year", date.year());
67
+ }
68
+
69
+ return components;
70
+ }
71
+ }
@@ -0,0 +1,26 @@
1
+ import { ParsingContext } from "../../../chrono";
2
+ import { ParsingComponents } from "../../../results";
3
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
4
+
5
+ const PATTERN = new RegExp("([0-9]|0[1-9]|1[012])/([0-9]{4})" + "", "i");
6
+
7
+ const MONTH_GROUP = 1;
8
+ const YEAR_GROUP = 2;
9
+
10
+ /**
11
+ * Month/Year date format with slash "/" (also "-" and ".") between numbers
12
+ * - 11/05
13
+ * - 06/2005
14
+ */
15
+ export default class ENSlashMonthFormatParser extends AbstractParserWithWordBoundaryChecking {
16
+ innerPattern(): RegExp {
17
+ return PATTERN;
18
+ }
19
+
20
+ innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
21
+ const year = parseInt(match[YEAR_GROUP]);
22
+ const month = parseInt(match[MONTH_GROUP]);
23
+
24
+ return context.createParsingComponents().imply("day", 1).assign("month", month).assign("year", year);
25
+ }
26
+ }
@@ -0,0 +1,55 @@
1
+ import { ParsingContext } from "../../../chrono";
2
+ import { ParsingComponents } from "../../../results";
3
+ import { Meridiem } from "../../../index";
4
+ import { AbstractTimeExpressionParser } from "../../../common/parsers/AbstractTimeExpressionParser";
5
+
6
+ export default class ENTimeExpressionParser extends AbstractTimeExpressionParser {
7
+ constructor(strictMode) {
8
+ super(strictMode);
9
+ }
10
+
11
+ followingPhase(): string {
12
+ return "\\s*(?:\\-|\\–|\\~|\\〜|to|\\?)\\s*";
13
+ }
14
+
15
+ primaryPrefix(): string {
16
+ return "(?:(?:alle|dalle)\\s*)??";
17
+ }
18
+
19
+ primarySuffix(): string {
20
+ return "(?:\\s*(?:o\\W*in punto|alle\\s*sera|in\\s*del\\s*(?:mattina|pomeriggio)))?(?!/)(?=\\W|$)";
21
+ }
22
+
23
+ extractPrimaryTimeComponents(context: ParsingContext, match: RegExpMatchArray): null | ParsingComponents {
24
+ const components = super.extractPrimaryTimeComponents(context, match);
25
+ if (components) {
26
+ if (match[0].endsWith("sera")) {
27
+ const hour = components.get("hour");
28
+ if (hour >= 6 && hour < 12) {
29
+ components.assign("hour", components.get("hour") + 12);
30
+ components.assign("meridiem", Meridiem.PM);
31
+ } else if (hour < 6) {
32
+ components.assign("meridiem", Meridiem.AM);
33
+ }
34
+ }
35
+
36
+ if (match[0].endsWith("pomeriggio")) {
37
+ components.assign("meridiem", Meridiem.PM);
38
+ const hour = components.get("hour");
39
+ if (hour >= 0 && hour <= 6) {
40
+ components.assign("hour", components.get("hour") + 12);
41
+ }
42
+ }
43
+
44
+ if (match[0].endsWith("mattina")) {
45
+ components.assign("meridiem", Meridiem.AM);
46
+ const hour = components.get("hour");
47
+ if (hour < 12) {
48
+ components.assign("hour", components.get("hour"));
49
+ }
50
+ }
51
+ }
52
+
53
+ return components;
54
+ }
55
+ }
@@ -0,0 +1,25 @@
1
+ import { ParsingContext } from "../../../chrono";
2
+ import { parseTimeUnits, TIME_UNITS_PATTERN } from "../constants";
3
+ import { ParsingComponents } from "../../../results";
4
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
5
+ import { reverseTimeUnits } from "../../../utils/timeunits";
6
+
7
+ const PATTERN = new RegExp(`(${TIME_UNITS_PATTERN})\\s{0,5}(?:fa|prima|precedente)(?=(?:\\W|$))`, "i");
8
+ const STRICT_PATTERN = new RegExp(`(${TIME_UNITS_PATTERN})\\s{0,5}fa(?=(?:\\W|$))`, "i");
9
+
10
+ export default class ENTimeUnitAgoFormatParser extends AbstractParserWithWordBoundaryChecking {
11
+ constructor(private strictMode: boolean) {
12
+ super();
13
+ }
14
+
15
+ innerPattern(): RegExp {
16
+ return this.strictMode ? STRICT_PATTERN : PATTERN;
17
+ }
18
+
19
+ innerExtract(context: ParsingContext, match: RegExpMatchArray) {
20
+ const timeUnits = parseTimeUnits(match[1]);
21
+ const outputTimeUnits = reverseTimeUnits(timeUnits);
22
+
23
+ return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits);
24
+ }
25
+ }
@@ -0,0 +1,30 @@
1
+ import { TIME_UNITS_PATTERN, parseTimeUnits } from "../constants";
2
+ import { ParsingContext } from "../../../chrono";
3
+ import { ParsingComponents } from "../../../results";
4
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
5
+ import { reverseTimeUnits } from "../../../utils/timeunits";
6
+
7
+ const PATTERN = new RegExp(
8
+ `(questo|ultimo|passato|prossimo|dopo|questa|ultima|passata|prossima|\\+|-)\\s*(${TIME_UNITS_PATTERN})(?=\\W|$)`,
9
+ "i"
10
+ );
11
+
12
+ export default class ENTimeUnitCasualRelativeFormatParser extends AbstractParserWithWordBoundaryChecking {
13
+ innerPattern(): RegExp {
14
+ return PATTERN;
15
+ }
16
+
17
+ innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
18
+ const prefix = match[1].toLowerCase();
19
+ let timeUnits = parseTimeUnits(match[2]);
20
+ switch (prefix) {
21
+ case "last":
22
+ case "past":
23
+ case "-":
24
+ timeUnits = reverseTimeUnits(timeUnits);
25
+ break;
26
+ }
27
+
28
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
29
+ }
30
+ }
@@ -0,0 +1,27 @@
1
+ import { ParsingContext } from "../../../chrono";
2
+ import { parseTimeUnits, TIME_UNITS_PATTERN } from "../constants";
3
+ import { ParsingComponents } from "../../../results";
4
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
5
+
6
+ const PATTERN = new RegExp(
7
+ `(${TIME_UNITS_PATTERN})\\s{0,5}(?:dopo|più tardi|da adesso|avanti|oltre|a seguire)` + "(?=(?:\\W|$))",
8
+ "i"
9
+ );
10
+
11
+ const STRICT_PATTERN = new RegExp("" + "(" + TIME_UNITS_PATTERN + ")" + "(dopo|più tardi)" + "(?=(?:\\W|$))", "i");
12
+ const GROUP_NUM_TIMEUNITS = 1;
13
+
14
+ export default class ENTimeUnitLaterFormatParser extends AbstractParserWithWordBoundaryChecking {
15
+ constructor(private strictMode: boolean) {
16
+ super();
17
+ }
18
+
19
+ innerPattern(): RegExp {
20
+ return this.strictMode ? STRICT_PATTERN : PATTERN;
21
+ }
22
+
23
+ innerExtract(context: ParsingContext, match: RegExpMatchArray) {
24
+ const fragments = parseTimeUnits(match[GROUP_NUM_TIMEUNITS]);
25
+ return ParsingComponents.createRelativeFromReference(context.reference, fragments);
26
+ }
27
+ }
@@ -0,0 +1,26 @@
1
+ import { TIME_UNITS_PATTERN, parseTimeUnits } from "../constants";
2
+ import { ParsingContext } from "../../../chrono";
3
+ import { ParsingComponents } from "../../../results";
4
+ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
5
+
6
+ const PATTERN_WITH_PREFIX = new RegExp(
7
+ `(?:within|in|for)\\s*` +
8
+ `(?:(?:più o meno|intorno|approssimativamente|verso|verso le)\\s*(?:~\\s*)?)?(${TIME_UNITS_PATTERN})(?=\\W|$)`,
9
+ "i"
10
+ );
11
+
12
+ const PATTERN_WITHOUT_PREFIX = new RegExp(
13
+ `(?:(?:più o meno|intorno|approssimativamente|verso|verso le)\\s*(?:~\\s*)?)?(${TIME_UNITS_PATTERN})(?=\\W|$)`,
14
+ "i"
15
+ );
16
+
17
+ export default class ENTimeUnitWithinFormatParser extends AbstractParserWithWordBoundaryChecking {
18
+ innerPattern(context: ParsingContext): RegExp {
19
+ return context.option.forwardDate ? PATTERN_WITHOUT_PREFIX : PATTERN_WITH_PREFIX;
20
+ }
21
+
22
+ innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents {
23
+ const timeUnits = parseTimeUnits(match[1]);
24
+ return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
25
+ }
26
+ }
@@ -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 "../../../common/calculation/weekdays";
7
+
8
+ const PATTERN = new RegExp(
9
+ "(?:(?:\\,|\\(|\\()\\s*)?" +
10
+ "(?:il\\s*?)?" +
11
+ "(?:(questa|l'ultima|scorsa|prossima)\\s*)?" +
12
+ `(${matchAnyPattern(WEEKDAY_DICTIONARY)})` +
13
+ "(?:\\s*(?:\\,|\\)|\\)))?" +
14
+ "(?:\\s*(questa|l'ultima|scorsa|prossima)\\s*settimana)?" +
15
+ "(?=\\W|$)",
16
+ "i"
17
+ );
18
+
19
+ const PREFIX_GROUP = 1;
20
+ const WEEKDAY_GROUP = 2;
21
+ const POSTFIX_GROUP = 3;
22
+
23
+ export default class ITWeekdayParser 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 weekday = WEEKDAY_DICTIONARY[dayOfWeek];
31
+ const prefix = match[PREFIX_GROUP];
32
+ const postfix = match[POSTFIX_GROUP];
33
+ let modifierWord = prefix || postfix;
34
+ modifierWord = modifierWord || "";
35
+ modifierWord = modifierWord.toLowerCase();
36
+
37
+ let modifier = null;
38
+ if (modifierWord == "ultima" || modifierWord == "scorsa") {
39
+ modifier = "ultima";
40
+ } else if (modifierWord == "prossima") {
41
+ modifier = "prossima";
42
+ } else if (modifierWord == "questa") {
43
+ modifier = "questa";
44
+ }
45
+ return createParsingComponentsAtWeekday(context.reference, weekday, modifier);
46
+ }
47
+ }
@@ -0,0 +1,17 @@
1
+ /*
2
+
3
+ */
4
+
5
+ import AbstractMergeDateRangeRefiner from "../../../common/refiners/AbstractMergeDateRangeRefiner";
6
+
7
+ /**
8
+ * Merging before and after results (see. AbstractMergeDateRangeRefiner)
9
+ * This implementation should provide English connecting phases
10
+ * - 2020-02-13 [to] 2020-02-13
11
+ * - Wednesday [-] Friday
12
+ */
13
+ export default class ENMergeDateRangeRefiner extends AbstractMergeDateRangeRefiner {
14
+ patternBetween(): RegExp {
15
+ return /^\s*(to|-)\s*$/i;
16
+ }
17
+ }
@@ -0,0 +1,13 @@
1
+ import AbstractMergeDateTimeRefiner from "../../../common/refiners/AbstractMergeDateTimeRefiner";
2
+
3
+ /**
4
+ * Merging date-only result and time-only result (see. AbstractMergeDateTimeRefiner).
5
+ * This implementation should provide English connecting phases
6
+ * - 2020-02-13 [at] 6pm
7
+ * - Tomorrow [after] 7am
8
+ */
9
+ export default class ENMergeDateTimeRefiner extends AbstractMergeDateTimeRefiner {
10
+ patternBetween(): RegExp {
11
+ return new RegExp("^\\s*(T|alle|dopo|prima|il|di|del|delle|,|-)?\\s*$");
12
+ }
13
+ }
@@ -0,0 +1,58 @@
1
+ import { MergingRefiner } from "../../../common/abstractRefiners";
2
+ import { ParsingComponents, ParsingResult, ReferenceWithTimezone } from "../../../results";
3
+ import { parseTimeUnits } from "../constants";
4
+ import { reverseTimeUnits } from "../../../utils/timeunits";
5
+
6
+ function hasImpliedEarlierReferenceDate(result: ParsingResult): boolean {
7
+ return result.text.match(/\s+(prima|dal)$/i) != null;
8
+ }
9
+
10
+ function hasImpliedLaterReferenceDate(result: ParsingResult): boolean {
11
+ return result.text.match(/\s+(dopo|dal|fino)$/i) != null;
12
+ }
13
+
14
+ /**
15
+ * Merges an absolute date with a relative date.
16
+ * - 2 weeks before 2020-02-13
17
+ * - 2 days after next Friday
18
+ */
19
+ export default class ENMergeRelativeDateRefiner extends MergingRefiner {
20
+ patternBetween(): RegExp {
21
+ return /^\s*$/i;
22
+ }
23
+
24
+ shouldMergeResults(textBetween: string, currentResult: ParsingResult, nextResult: ParsingResult): boolean {
25
+ // Dates need to be next to each other to get merged
26
+ if (!textBetween.match(this.patternBetween())) {
27
+ return false;
28
+ }
29
+
30
+ // Check if any relative tokens were swallowed by the first date.
31
+ // E.g. [<relative_date1> from] [<date2>]
32
+ if (!hasImpliedEarlierReferenceDate(currentResult) && !hasImpliedLaterReferenceDate(currentResult)) {
33
+ return false;
34
+ }
35
+
36
+ // make sure that <date2> implies an absolute date
37
+ return !!nextResult.start.get("day") && !!nextResult.start.get("month") && !!nextResult.start.get("year");
38
+ }
39
+
40
+ mergeResults(textBetween: string, currentResult: ParsingResult, nextResult: ParsingResult): ParsingResult {
41
+ let timeUnits = parseTimeUnits(currentResult.text);
42
+ if (hasImpliedEarlierReferenceDate(currentResult)) {
43
+ timeUnits = reverseTimeUnits(timeUnits);
44
+ }
45
+
46
+ const components = ParsingComponents.createRelativeFromReference(
47
+ new ReferenceWithTimezone(nextResult.start.date()),
48
+ timeUnits
49
+ );
50
+
51
+ return new ParsingResult(
52
+ nextResult.reference,
53
+ currentResult.index,
54
+ `${currentResult.text}${textBetween}${nextResult.text}`,
55
+ components
56
+ );
57
+ }
58
+ }