timelang 0.1.0 → 0.3.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.
- package/LICENSE +21 -0
- package/README.md +1 -2
- package/dist/index.cjs +550 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +550 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -270,8 +270,21 @@ var lexer = import_moo.default.compile({
|
|
|
270
270
|
"sat",
|
|
271
271
|
"sun"
|
|
272
272
|
],
|
|
273
|
+
// Ago keyword for relative dates
|
|
274
|
+
kw_ago: ["ago"],
|
|
275
|
+
// Weekend and night keywords
|
|
276
|
+
kw_weekend: ["weekend"],
|
|
277
|
+
kw_tonight: ["tonight"],
|
|
278
|
+
kw_night: ["night"],
|
|
279
|
+
kw_fortnight: ["fortnight", "fortnights"],
|
|
273
280
|
// Other keywords
|
|
274
|
-
otherKeyword: ["fiscal", "fy", "daily", "weekly", "monthly", "yearly", "annually", "
|
|
281
|
+
otherKeyword: ["fiscal", "fy", "daily", "weekly", "monthly", "yearly", "annually", "hence", "later", "earlier"],
|
|
282
|
+
// Business keywords
|
|
283
|
+
kw_business: ["business"],
|
|
284
|
+
// EOD/COB keywords
|
|
285
|
+
kw_eod: ["eod"],
|
|
286
|
+
kw_cob: ["cob"],
|
|
287
|
+
kw_close: ["close"]
|
|
275
288
|
})
|
|
276
289
|
// Keywords are matched against lowercase input
|
|
277
290
|
},
|
|
@@ -324,6 +337,13 @@ var makeRelative = (direction, duration) => ({
|
|
|
324
337
|
direction,
|
|
325
338
|
duration
|
|
326
339
|
});
|
|
340
|
+
var makeRelativeDate = (direction, duration, baseDate, time2) => ({
|
|
341
|
+
nodeType: "relativeDate",
|
|
342
|
+
direction,
|
|
343
|
+
duration,
|
|
344
|
+
baseDate,
|
|
345
|
+
time: time2
|
|
346
|
+
});
|
|
327
347
|
var makeTitled = (title, expression, titleStart, titleEnd) => ({
|
|
328
348
|
nodeType: "titled",
|
|
329
349
|
title: title.trim(),
|
|
@@ -559,10 +579,14 @@ var grammar = {
|
|
|
559
579
|
{ "name": "expression", "symbols": ["range"], "postprocess": first },
|
|
560
580
|
{ "name": "expression", "symbols": ["span"], "postprocess": first },
|
|
561
581
|
{ "name": "expression", "symbols": ["relative"], "postprocess": first },
|
|
582
|
+
{ "name": "expression", "symbols": ["relativeDate"], "postprocess": first },
|
|
583
|
+
{ "name": "expression", "symbols": ["lastDayOfMonthExpr"], "postprocess": first },
|
|
584
|
+
{ "name": "expression", "symbols": ["date"], "postprocess": first },
|
|
562
585
|
{ "name": "expression", "symbols": ["fuzzy"], "postprocess": first },
|
|
563
586
|
{ "name": "expression", "symbols": ["forDuration"], "postprocess": first },
|
|
564
587
|
{ "name": "expression", "symbols": ["duration"], "postprocess": first },
|
|
565
|
-
{ "name": "
|
|
588
|
+
{ "name": "lastDayOfMonthExpr", "symbols": ["lastRelative", "_", "dayUnit", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ month: d[6], lastDayOfMonth: true }) },
|
|
589
|
+
{ "name": "lastDayOfMonthExpr", "symbols": ["lastRelative", "_", "dayUnit", "_", "ofConnector", "_", "theConnector", "_", "monthUnit"], "postprocess": (d) => makeDate({ lastDayOfMonth: true, monthFromRef: true }) },
|
|
566
590
|
{ "name": "forDuration", "symbols": ["forConnector", "_", "duration"], "postprocess": (d) => d[2] },
|
|
567
591
|
{ "name": "range", "symbols": ["date", "_", "toConnector", "_", "date"], "postprocess": (d) => makeRange(d[0], d[4]) },
|
|
568
592
|
{ "name": "range", "symbols": ["fromConnector", "_", "date", "_", "toConnector", "_", "date"], "postprocess": (d) => makeRange(d[2], d[6]) },
|
|
@@ -644,6 +668,44 @@ var grammar = {
|
|
|
644
668
|
{ "name": "relative", "symbols": ["inConnector", "_", "theConnector", "_", "pastRelative", "_", "unit"], "postprocess": (d) => makeRelative("past", makeDuration(1, d[6])) },
|
|
645
669
|
{ "name": "relative", "symbols": ["inConnector", "_", "theConnector", "_", "comingRelative", "_", "unit"], "postprocess": (d) => makeRelative("future", makeDuration(1, d[6])) },
|
|
646
670
|
{ "name": "relative", "symbols": ["inConnector", "_", "theConnector", "_", "upcomingRelative", "_", "unit"], "postprocess": (d) => makeRelative("future", makeDuration(1, d[6])) },
|
|
671
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", d[0]) },
|
|
672
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "agoConnector", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("past", d[0], void 0, d[6]) },
|
|
673
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "agoConnector", "_", "atConnector", "_", "timeWord"], "postprocess": (d) => makeRelativeDate("past", d[0], void 0, { special: d[6] }) },
|
|
674
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "duration"], "postprocess": (d) => makeRelativeDate("future", d[2]) },
|
|
675
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "duration", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("future", d[2], void 0, d[6]) },
|
|
676
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "duration", "_", "atConnector", "_", "timeWord"], "postprocess": (d) => makeRelativeDate("future", d[2], void 0, { special: d[6] }) },
|
|
677
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "now"], "postprocess": (d) => makeRelativeDate("future", d[0]) },
|
|
678
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "now", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("future", d[0], void 0, d[8]) },
|
|
679
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "now", "_", "atConnector", "_", "timeWord"], "postprocess": (d) => makeRelativeDate("future", d[0], void 0, { special: d[8] }) },
|
|
680
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "today"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "today" })) },
|
|
681
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "today", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "today" }), d[8]) },
|
|
682
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "tomorrow"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "tomorrow" })) },
|
|
683
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "tomorrow", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "tomorrow" }), d[8]) },
|
|
684
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "yesterday"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "yesterday" })) },
|
|
685
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "henceConnector"], "postprocess": (d) => makeRelativeDate("future", d[0]) },
|
|
686
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "laterConnector"], "postprocess": (d) => makeRelativeDate("future", d[0]) },
|
|
687
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "beforeConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("past", d[0], d[4]) },
|
|
688
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "afterConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("future", d[0], d[4]) },
|
|
689
|
+
{ "name": "relativeDate", "symbols": ["theConnector", "_", "dayUnit", "_", "beforeConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("past", makeDuration(1, "day"), d[6]) },
|
|
690
|
+
{ "name": "relativeDate", "symbols": ["theConnector", "_", "dayUnit", "_", "afterConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("future", makeDuration(1, "day"), d[6]) },
|
|
691
|
+
{ "name": "relativeDate", "symbols": ["dayUnit", "_", "beforeConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("past", makeDuration(1, "day"), d[4]) },
|
|
692
|
+
{ "name": "relativeDate", "symbols": ["dayUnit", "_", "afterConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("future", makeDuration(1, "day"), d[4]) },
|
|
693
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "unit", "_", "beforeConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("past", makeDuration(parseWordNumber(d[0]), d[2]), d[6]) },
|
|
694
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "unit", "_", "afterConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("future", makeDuration(parseWordNumber(d[0]), d[2]), d[6]) },
|
|
695
|
+
{ "name": "relativeDate", "symbols": ["nextRelative", "_", "businessKeyword", "_", "dayOrDaysUnit"], "postprocess": (d) => makeRelativeDate("future", makeDuration(1, "businessDay")) },
|
|
696
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "number", "_", "businessKeyword", "_", "dayOrDaysUnit"], "postprocess": (d) => makeRelativeDate("future", makeDuration(d[2], "businessDay")) },
|
|
697
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "wordNumber", "_", "businessKeyword", "_", "dayOrDaysUnit"], "postprocess": (d) => makeRelativeDate("future", makeDuration(parseWordNumber(d[2]), "businessDay")) },
|
|
698
|
+
{ "name": "relativeDate", "symbols": ["number", "_", "businessKeyword", "_", "dayOrDaysUnit", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(d[0], "businessDay")) },
|
|
699
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "businessKeyword", "_", "dayOrDaysUnit", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(parseWordNumber(d[0]), "businessDay")) },
|
|
700
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "fortnightKeyword", "_", "fromConnector", "_", "now"], "postprocess": (d) => makeRelativeDate("future", makeDuration(parseWordNumber(d[0]) * 2, "week")) },
|
|
701
|
+
{ "name": "relativeDate", "symbols": ["number", "_", "fortnightKeyword", "_", "fromConnector", "_", "now"], "postprocess": (d) => makeRelativeDate("future", makeDuration(d[0] * 2, "week")) },
|
|
702
|
+
{ "name": "relativeDate", "symbols": ["fortnightKeyword", "_", "fromConnector", "_", "now"], "postprocess": (d) => makeRelativeDate("future", makeDuration(2, "week")) },
|
|
703
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "wordNumber", "_", "fortnightKeyword"], "postprocess": (d) => makeRelativeDate("future", makeDuration(parseWordNumber(d[2]) * 2, "week")) },
|
|
704
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "number", "_", "fortnightKeyword"], "postprocess": (d) => makeRelativeDate("future", makeDuration(d[2] * 2, "week")) },
|
|
705
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "fortnightKeyword"], "postprocess": (d) => makeRelativeDate("future", makeDuration(2, "week")) },
|
|
706
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "fortnightKeyword", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(parseWordNumber(d[0]) * 2, "week")) },
|
|
707
|
+
{ "name": "relativeDate", "symbols": ["number", "_", "fortnightKeyword", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(d[0] * 2, "week")) },
|
|
708
|
+
{ "name": "relativeDate", "symbols": ["fortnightKeyword", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(2, "week")) },
|
|
647
709
|
{ "name": "fuzzy", "symbols": ["quarter"], "postprocess": (d) => makeFuzzy({ period: "quarter", quarter: parseQuarter(d[0].value) }) },
|
|
648
710
|
{ "name": "fuzzy", "symbols": ["quarter", "_", "year"], "postprocess": (d) => makeFuzzy({ period: "quarter", quarter: parseQuarter(d[0].value), year: d[2] }) },
|
|
649
711
|
{ "name": "fuzzy", "symbols": ["half"], "postprocess": (d) => makeFuzzy({ period: "half", half: parseHalf(d[0].value) }) },
|
|
@@ -726,8 +788,31 @@ var grammar = {
|
|
|
726
788
|
{ "name": "fuzzy", "symbols": ["lateModifier", "_", "thisRelative", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[4], modifier: "late", relative: "this" }) },
|
|
727
789
|
{ "name": "fuzzy", "symbols": ["beginningConnector", "_", "ofConnector", "_", "theConnector", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[6], modifier: "beginning" }) },
|
|
728
790
|
{ "name": "fuzzy", "symbols": ["middleConnector", "_", "ofConnector", "_", "theConnector", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[6], modifier: "middle" }) },
|
|
729
|
-
{ "name": "fuzzy", "symbols": ["lastRelative", "_", "unit", "_", "ofConnector", "_", "month"], "postprocess": (d
|
|
730
|
-
|
|
791
|
+
{ "name": "fuzzy", "symbols": ["lastRelative", "_", "unit", "_", "ofConnector", "_", "month"], "postprocess": (d, _, reject) => {
|
|
792
|
+
if (d[2].toLowerCase() === "day" || d[2].toLowerCase() === "days") return reject;
|
|
793
|
+
return makeFuzzy({ period: "month", month: d[6], modifier: "late" });
|
|
794
|
+
} },
|
|
795
|
+
{ "name": "fuzzy", "symbols": ["ordinalWord", "_", "unit", "_", "ofConnector", "_", "month"], "postprocess": (d, _, reject) => {
|
|
796
|
+
if (d[2].toLowerCase() === "day" || d[2].toLowerCase() === "days") return reject;
|
|
797
|
+
return makeFuzzy({ period: "month", month: d[6], modifier: parseOrdinalWord(d[0]) <= 2 ? "early" : parseOrdinalWord(d[0]) >= 4 ? "late" : "mid" });
|
|
798
|
+
} },
|
|
799
|
+
{ "name": "fuzzy", "symbols": ["weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "this" }) },
|
|
800
|
+
{ "name": "fuzzy", "symbols": ["theConnector", "_", "weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "this" }) },
|
|
801
|
+
{ "name": "fuzzy", "symbols": ["thisRelative", "_", "weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "this" }) },
|
|
802
|
+
{ "name": "fuzzy", "symbols": ["nextRelative", "_", "weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "next" }) },
|
|
803
|
+
{ "name": "fuzzy", "symbols": ["lastRelative", "_", "weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "last" }) },
|
|
804
|
+
{ "name": "fuzzy", "symbols": ["tonightKeyword"], "postprocess": (d) => makeFuzzy({ period: "tonight" }) },
|
|
805
|
+
{ "name": "fuzzy", "symbols": ["nightKeyword"], "postprocess": (d) => makeFuzzy({ period: "night" }) },
|
|
806
|
+
{ "name": "fuzzy", "symbols": ["lastRelative", "_", "nightKeyword"], "postprocess": (d) => makeFuzzy({ period: "night", relative: "last" }) },
|
|
807
|
+
{ "name": "fuzzy", "symbols": ["tomorrow", "_", "nightKeyword"], "postprocess": (d) => makeFuzzy({ period: "night", relative: "tomorrow" }) },
|
|
808
|
+
{ "name": "fuzzy", "symbols": ["weekday", "_", "nightKeyword"], "postprocess": (d) => makeFuzzy({ period: "night", weekday: d[0] }) },
|
|
809
|
+
{ "name": "fuzzy", "symbols": ["laterKeyword", "_", "today"], "postprocess": (d) => makeFuzzy({ period: "day", modifier: "later" }) },
|
|
810
|
+
{ "name": "fuzzy", "symbols": ["earlierKeyword", "_", "today"], "postprocess": (d) => makeFuzzy({ period: "day", modifier: "earlier" }) },
|
|
811
|
+
{ "name": "fuzzy", "symbols": ["laterKeyword", "_", "thisRelative", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[4], modifier: "later", relative: "this" }) },
|
|
812
|
+
{ "name": "fuzzy", "symbols": ["earlierKeyword", "_", "thisRelative", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[4], modifier: "earlier", relative: "this" }) },
|
|
813
|
+
{ "name": "fuzzy", "symbols": ["weekKeyword", "_", "number"], "postprocess": (d) => makeFuzzy({ period: "weekNumber", weekNumber: d[2] }) },
|
|
814
|
+
{ "name": "fuzzy", "symbols": ["weekKeyword", "_", "number", "_", "year"], "postprocess": (d) => makeFuzzy({ period: "weekNumber", weekNumber: d[2], year: d[4] }) },
|
|
815
|
+
{ "name": "fuzzy", "symbols": ["theConnector", "_", "weekKeyword", "_", "ofConnector", "_", "date"], "postprocess": (d) => makeFuzzy({ period: "weekOf", baseDate: d[6] }) },
|
|
731
816
|
{ "name": "duration", "symbols": ["number", "_", "unit"], "postprocess": (d) => makeDuration(d[0], d[2]) },
|
|
732
817
|
{ "name": "duration", "symbols": ["wordNumber", "_", "unit"], "postprocess": (d) => makeDuration(parseWordNumber(d[0]), d[2]) },
|
|
733
818
|
{ "name": "duration", "symbols": ["abbreviatedDuration"], "postprocess": (d) => d[0] },
|
|
@@ -755,6 +840,7 @@ var grammar = {
|
|
|
755
840
|
return makeDuration(value, unitMap[match[2]]);
|
|
756
841
|
} },
|
|
757
842
|
{ "name": "date", "symbols": ["specialDay"], "postprocess": (d) => makeDate({ special: d[0] }) },
|
|
843
|
+
{ "name": "date", "symbols": ["ordinalWeekdayOfMonth"], "postprocess": first },
|
|
758
844
|
{ "name": "date", "symbols": ["relativeWeekday"], "postprocess": first },
|
|
759
845
|
{ "name": "date", "symbols": ["weekday"], "postprocess": (d) => makeDate({ weekday: d[0] }) },
|
|
760
846
|
{ "name": "date", "symbols": ["monthDayYear"], "postprocess": first },
|
|
@@ -769,6 +855,8 @@ var grammar = {
|
|
|
769
855
|
{ "name": "date", "symbols": ["monthOnly"], "postprocess": first },
|
|
770
856
|
{ "name": "date", "symbols": ["yearOnly"], "postprocess": first },
|
|
771
857
|
{ "name": "date", "symbols": ["timeOnly"], "postprocess": first },
|
|
858
|
+
{ "name": "date", "symbols": ["dayOnly"], "postprocess": first },
|
|
859
|
+
{ "name": "date", "symbols": ["eodCobDate"], "postprocess": first },
|
|
772
860
|
{ "name": "monthDayCompact", "symbols": [lexer.has("monthDayCompact") ? { type: "monthDayCompact" } : monthDayCompact], "postprocess": (d) => {
|
|
773
861
|
const parsed = parseMonthDayCompact(d[0].value);
|
|
774
862
|
return makeDate({ month: parsed.month, day: parsed.day });
|
|
@@ -785,6 +873,17 @@ var grammar = {
|
|
|
785
873
|
} },
|
|
786
874
|
{ "name": "timeOnly", "symbols": ["time"], "postprocess": (d) => makeDate({ time: d[0], timeOnly: true }) },
|
|
787
875
|
{ "name": "timeOnly", "symbols": ["timeWord"], "postprocess": (d) => makeDate({ time: { special: d[0] }, timeOnly: true }) },
|
|
876
|
+
{ "name": "dayOnly", "symbols": ["theConnector", "_", "dayNumber"], "postprocess": (d) => makeDate({ day: d[2], dayOnly: true }) },
|
|
877
|
+
{ "name": "dayOnly", "symbols": ["onConnector", "_", "theConnector", "_", "dayNumber"], "postprocess": (d) => makeDate({ day: d[4], dayOnly: true }) },
|
|
878
|
+
{ "name": "eodCobDate", "symbols": ["eodKeyword"], "postprocess": (d) => makeDate({ special: "today", time: { hour: 23, minute: 59 } }) },
|
|
879
|
+
{ "name": "eodCobDate", "symbols": ["cobKeyword"], "postprocess": (d) => makeDate({ special: "today", time: { hour: 17, minute: 0 } }) },
|
|
880
|
+
{ "name": "eodCobDate", "symbols": ["eodKeyword", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], time: { hour: 23, minute: 59 } }) },
|
|
881
|
+
{ "name": "eodCobDate", "symbols": ["cobKeyword", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], time: { hour: 17, minute: 0 } }) },
|
|
882
|
+
{ "name": "eodCobDate", "symbols": ["eodKeyword", "_", "specialDay"], "postprocess": (d) => makeDate({ special: d[2], time: { hour: 23, minute: 59 } }) },
|
|
883
|
+
{ "name": "eodCobDate", "symbols": ["cobKeyword", "_", "specialDay"], "postprocess": (d) => makeDate({ special: d[2], time: { hour: 17, minute: 0 } }) },
|
|
884
|
+
{ "name": "eodCobDate", "symbols": ["endConnector", "_", "ofConnector", "_", "dayUnit", "_", "specialDay"], "postprocess": (d) => makeDate({ special: d[6], time: { hour: 23, minute: 59 } }) },
|
|
885
|
+
{ "name": "eodCobDate", "symbols": ["closeKeyword", "_", "ofConnector", "_", "businessKeyword", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[6], time: { hour: 17, minute: 0 } }) },
|
|
886
|
+
{ "name": "eodCobDate", "symbols": ["closeKeyword", "_", "ofConnector", "_", "businessKeyword", "_", "specialDay"], "postprocess": (d) => makeDate({ special: d[6], time: { hour: 17, minute: 0 } }) },
|
|
788
887
|
{ "name": "specialDay", "symbols": ["today"], "postprocess": (d) => "today" },
|
|
789
888
|
{ "name": "specialDay", "symbols": ["tomorrow"], "postprocess": (d) => "tomorrow" },
|
|
790
889
|
{ "name": "specialDay", "symbols": ["yesterday"], "postprocess": (d) => "yesterday" },
|
|
@@ -793,7 +892,8 @@ var grammar = {
|
|
|
793
892
|
{ "name": "specialDay", "symbols": ["dayUnit", "_", "afterConnector", "_", "tomorrow"], "postprocess": (d) => "dayAfterTomorrow" },
|
|
794
893
|
{ "name": "specialDay", "symbols": ["theConnector", "_", "dayUnit", "_", "beforeConnector", "_", "yesterday"], "postprocess": (d) => "dayBeforeYesterday" },
|
|
795
894
|
{ "name": "specialDay", "symbols": ["dayUnit", "_", "beforeConnector", "_", "yesterday"], "postprocess": (d) => "dayBeforeYesterday" },
|
|
796
|
-
{ "name": "dayUnit", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d) => d[0].value === "day" ? d[0] :
|
|
895
|
+
{ "name": "dayUnit", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => d[0].value === "day" ? d[0] : reject },
|
|
896
|
+
{ "name": "dayOrDaysUnit", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => d[0].value === "day" || d[0].value === "days" ? d[0] : reject },
|
|
797
897
|
{ "name": "relativeWeekday", "symbols": ["nextRelative", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], relative: "next" }) },
|
|
798
898
|
{ "name": "relativeWeekday", "symbols": ["lastRelative", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], relative: "last" }) },
|
|
799
899
|
{ "name": "relativeWeekday", "symbols": ["thisRelative", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], relative: "this" }) },
|
|
@@ -808,6 +908,14 @@ var grammar = {
|
|
|
808
908
|
{ "name": "monthDay", "symbols": ["theConnector", "_", "dayNumber", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ month: d[6], day: d[2] }) },
|
|
809
909
|
{ "name": "monthDay", "symbols": ["month", "_", "ordinalWord"], "postprocess": (d) => makeDate({ month: d[0], day: parseOrdinalWord(d[2]) }) },
|
|
810
910
|
{ "name": "monthDay", "symbols": ["month", "_", "theConnector", "_", "dayNumber"], "postprocess": (d) => makeDate({ month: d[0], day: d[4] }) },
|
|
911
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["ordinalWord", "_", "weekday", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ ordinalWeekday: parseOrdinalWord(d[0]), weekday: d[2], month: d[6] }) },
|
|
912
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["lastRelative", "_", "weekday", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ ordinalWeekday: -1, weekday: d[2], month: d[6] }) },
|
|
913
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["ordinalWord", "_", "weekday", "_", "ofConnector", "_", "theConnector", "_", "monthUnit"], "postprocess": (d) => makeDate({ ordinalWeekday: parseOrdinalWord(d[0]), weekday: d[2], monthFromRef: true }) },
|
|
914
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["lastRelative", "_", "weekday", "_", "ofConnector", "_", "theConnector", "_", "monthUnit"], "postprocess": (d) => makeDate({ ordinalWeekday: -1, weekday: d[2], monthFromRef: true }) },
|
|
915
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["ordinalWord", "_", "dayUnit", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ month: d[6], day: parseOrdinalWord(d[0]) }) },
|
|
916
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["lastRelative", "_", "dayUnit", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ month: d[6], day: -1, lastDayOfMonth: true }) },
|
|
917
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["lastRelative", "_", "dayUnit", "_", "ofConnector", "_", "theConnector", "_", "monthUnit"], "postprocess": (d) => makeDate({ lastDayOfMonth: true, monthFromRef: true }) },
|
|
918
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["ordinalWord", "_", "dayUnit", "_", "ofConnector", "_", "nextRelative", "_", "monthUnit"], "postprocess": (d) => makeDate({ ordinalWeekday: parseOrdinalWord(d[0]), dayOfMonth: true, nextMonth: true }) },
|
|
811
919
|
{ "name": "monthDayYear", "symbols": ["monthDay", "_", "year"], "postprocess": (d) => ({ ...d[0], year: d[2] }) },
|
|
812
920
|
{ "name": "monthDayYear", "symbols": ["monthDay", lexer.has("comma") ? { type: "comma" } : comma, "_", "year"], "postprocess": (d) => ({ ...d[0], year: d[3] }) },
|
|
813
921
|
{ "name": "dateFormat", "symbols": [lexer.has("integer") ? { type: "integer" } : integer, lexer.has("dash") ? { type: "dash" } : dash, lexer.has("integer") ? { type: "integer" } : integer, lexer.has("dash") ? { type: "dash" } : dash, lexer.has("integer") ? { type: "integer" } : integer], "postprocess": (d) => {
|
|
@@ -829,6 +937,9 @@ var grammar = {
|
|
|
829
937
|
{ "name": "dateWithTime", "symbols": ["time", "_", "date"], "postprocess": (d) => ({ ...d[2], time: d[0] }) },
|
|
830
938
|
{ "name": "dateWithTime", "symbols": ["timeWord", "_", "date"], "postprocess": (d) => ({ ...d[2], time: { special: d[0] } }) },
|
|
831
939
|
{ "name": "dateWithTime", "symbols": ["date", "_", "time"], "postprocess": (d) => ({ ...d[0], time: d[2] }) },
|
|
940
|
+
{ "name": "dateWithTime", "symbols": ["timeWord", "_", "onConnector", "_", "date"], "postprocess": (d) => ({ ...d[4], time: { special: d[0] } }) },
|
|
941
|
+
{ "name": "dateWithTime", "symbols": ["timeWord", "_", "onConnector", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[4], time: { special: d[0] } }) },
|
|
942
|
+
{ "name": "dateWithTime", "symbols": ["midnight", "_", "tonightKeyword"], "postprocess": (d) => makeDate({ special: "tonight", time: { special: "midnight" } }) },
|
|
832
943
|
{ "name": "complexDate", "symbols": ["nextRelative", "_", "unit", "_", "weekday", "_", "time"], "postprocess": (d) => makeDate({ relative: "next", period: d[2], weekday: d[4], time: d[6] }) },
|
|
833
944
|
{ "name": "complexDate", "symbols": ["nextRelative", "_", "unit", "_", "weekday"], "postprocess": (d) => makeDate({ relative: "next", period: d[2], weekday: d[4] }) },
|
|
834
945
|
{ "name": "complexDate", "symbols": ["lastRelative", "_", "unit", "_", "weekday", "_", "time"], "postprocess": (d) => makeDate({ relative: "last", period: d[2], weekday: d[4], time: d[6] }) },
|
|
@@ -865,6 +976,45 @@ var grammar = {
|
|
|
865
976
|
if (d[1].value === "am" && hour === 12) hour = 0;
|
|
866
977
|
return { hour, minute: 0 };
|
|
867
978
|
} },
|
|
979
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "pastConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4], minute: 15 }) },
|
|
980
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "pastConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
981
|
+
let hour = d[4];
|
|
982
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
983
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
984
|
+
return { hour, minute: 15 };
|
|
985
|
+
} },
|
|
986
|
+
{ "name": "time", "symbols": ["halfWord", "_", "pastConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4], minute: 30 }) },
|
|
987
|
+
{ "name": "time", "symbols": ["halfWord", "_", "pastConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
988
|
+
let hour = d[4];
|
|
989
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
990
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
991
|
+
return { hour, minute: 30 };
|
|
992
|
+
} },
|
|
993
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "toConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4] - 1, minute: 45 }) },
|
|
994
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "toConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
995
|
+
let hour = d[4];
|
|
996
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
997
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
998
|
+
return { hour: hour - 1, minute: 45 };
|
|
999
|
+
} },
|
|
1000
|
+
{ "name": "time", "symbols": ["number", "_", "pastConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4], minute: d[0] }) },
|
|
1001
|
+
{ "name": "time", "symbols": ["number", "_", "pastConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
1002
|
+
let hour = d[4];
|
|
1003
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
1004
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
1005
|
+
return { hour, minute: d[0] };
|
|
1006
|
+
} },
|
|
1007
|
+
{ "name": "time", "symbols": ["number", "_", "toConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4] - 1, minute: 60 - d[0] }) },
|
|
1008
|
+
{ "name": "time", "symbols": ["number", "_", "toConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
1009
|
+
let hour = d[4];
|
|
1010
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
1011
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
1012
|
+
return { hour: hour - 1, minute: 60 - d[0] };
|
|
1013
|
+
} },
|
|
1014
|
+
{ "name": "time", "symbols": ["number", "_", "toConnector", "_", "noon"], "postprocess": (d) => ({ hour: 11, minute: 60 - d[0] }) },
|
|
1015
|
+
{ "name": "time", "symbols": ["number", "_", "toConnector", "_", "midnight"], "postprocess": (d) => ({ hour: 23, minute: 60 - d[0] }) },
|
|
1016
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "toConnector", "_", "noon"], "postprocess": (d) => ({ hour: 11, minute: 45 }) },
|
|
1017
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "toConnector", "_", "midnight"], "postprocess": (d) => ({ hour: 23, minute: 45 }) },
|
|
868
1018
|
{ "name": "timeWord", "symbols": ["noon"], "postprocess": (d) => "noon" },
|
|
869
1019
|
{ "name": "timeWord", "symbols": ["midnight"], "postprocess": (d) => "midnight" },
|
|
870
1020
|
{ "name": "number", "symbols": [lexer.has("integer") ? { type: "integer" } : integer], "postprocess": (d) => parseInt(d[0].value, 10) },
|
|
@@ -901,6 +1051,11 @@ var grammar = {
|
|
|
901
1051
|
if (val === "year" || val === "years" || val === "yr" || val === "yrs") return val;
|
|
902
1052
|
return reject;
|
|
903
1053
|
} },
|
|
1054
|
+
{ "name": "monthUnit", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => {
|
|
1055
|
+
const val = d[0].value.toLowerCase();
|
|
1056
|
+
if (val === "month" || val === "months" || val === "mo" || val === "mos") return val;
|
|
1057
|
+
return reject;
|
|
1058
|
+
} },
|
|
904
1059
|
{ "name": "wordNumber", "symbols": [lexer.has("wordNumber") ? { type: "wordNumber" } : wordNumber], "postprocess": (d) => d[0].value },
|
|
905
1060
|
{ "name": "ordinalWord", "symbols": [lexer.has("ordinalWord") ? { type: "ordinalWord" } : ordinalWord], "postprocess": (d) => d[0].value },
|
|
906
1061
|
{ "name": "ordinalWord", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => {
|
|
@@ -937,6 +1092,9 @@ var grammar = {
|
|
|
937
1092
|
{ "name": "beginningConnector", "symbols": [lexer.has("kw_beginning") ? { type: "kw_beginning" } : kw_beginning], "postprocess": first },
|
|
938
1093
|
{ "name": "startConnector", "symbols": [lexer.has("kw_start") ? { type: "kw_start" } : kw_start], "postprocess": first },
|
|
939
1094
|
{ "name": "middleConnector", "symbols": [lexer.has("kw_middle") ? { type: "kw_middle" } : kw_middle], "postprocess": first },
|
|
1095
|
+
{ "name": "agoConnector", "symbols": [lexer.has("kw_ago") ? { type: "kw_ago" } : kw_ago], "postprocess": first },
|
|
1096
|
+
{ "name": "henceConnector", "symbols": [lexer.has("otherKeyword") ? { type: "otherKeyword" } : otherKeyword], "postprocess": (d, _, reject) => d[0].value === "hence" ? d[0] : reject },
|
|
1097
|
+
{ "name": "laterConnector", "symbols": [lexer.has("otherKeyword") ? { type: "otherKeyword" } : otherKeyword], "postprocess": (d, _, reject) => d[0].value === "later" ? d[0] : reject },
|
|
940
1098
|
{ "name": "earlyModifier", "symbols": [lexer.has("kw_early") ? { type: "kw_early" } : kw_early], "postprocess": first },
|
|
941
1099
|
{ "name": "midModifier", "symbols": [lexer.has("kw_mid") ? { type: "kw_mid" } : kw_mid], "postprocess": first },
|
|
942
1100
|
{ "name": "lateModifier", "symbols": [lexer.has("kw_late") ? { type: "kw_late" } : kw_late], "postprocess": first },
|
|
@@ -953,6 +1111,28 @@ var grammar = {
|
|
|
953
1111
|
{ "name": "now", "symbols": [lexer.has("kw_now") ? { type: "kw_now" } : kw_now], "postprocess": first },
|
|
954
1112
|
{ "name": "noon", "symbols": [lexer.has("kw_noon") ? { type: "kw_noon" } : kw_noon], "postprocess": first },
|
|
955
1113
|
{ "name": "midnight", "symbols": [lexer.has("kw_midnight") ? { type: "kw_midnight" } : kw_midnight], "postprocess": first },
|
|
1114
|
+
{ "name": "quarterKeyword", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => d[0].value === "quarter" ? d[0] : reject },
|
|
1115
|
+
{ "name": "hourNumber", "symbols": [lexer.has("integer") ? { type: "integer" } : integer], "postprocess": (d, _, reject) => {
|
|
1116
|
+
const val = parseInt(d[0].value, 10);
|
|
1117
|
+
if (val < 1 || val > 12) return reject;
|
|
1118
|
+
return val;
|
|
1119
|
+
} },
|
|
1120
|
+
{ "name": "pastConnector", "symbols": [lexer.has("kw_past") ? { type: "kw_past" } : kw_past], "postprocess": first },
|
|
1121
|
+
{ "name": "weekendKeyword", "symbols": [lexer.has("kw_weekend") ? { type: "kw_weekend" } : kw_weekend], "postprocess": first },
|
|
1122
|
+
{ "name": "tonightKeyword", "symbols": [lexer.has("kw_tonight") ? { type: "kw_tonight" } : kw_tonight], "postprocess": first },
|
|
1123
|
+
{ "name": "nightKeyword", "symbols": [lexer.has("kw_night") ? { type: "kw_night" } : kw_night], "postprocess": first },
|
|
1124
|
+
{ "name": "fortnightKeyword", "symbols": [lexer.has("kw_fortnight") ? { type: "kw_fortnight" } : kw_fortnight], "postprocess": first },
|
|
1125
|
+
{ "name": "laterKeyword", "symbols": [lexer.has("otherKeyword") ? { type: "otherKeyword" } : otherKeyword], "postprocess": (d, _, reject) => d[0].value === "later" ? d[0] : reject },
|
|
1126
|
+
{ "name": "earlierKeyword", "symbols": [lexer.has("otherKeyword") ? { type: "otherKeyword" } : otherKeyword], "postprocess": (d, _, reject) => d[0].value === "earlier" ? d[0] : reject },
|
|
1127
|
+
{ "name": "weekKeyword", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => {
|
|
1128
|
+
const val = d[0].value.toLowerCase();
|
|
1129
|
+
if (val === "week" || val === "weeks") return d[0];
|
|
1130
|
+
return reject;
|
|
1131
|
+
} },
|
|
1132
|
+
{ "name": "businessKeyword", "symbols": [lexer.has("kw_business") ? { type: "kw_business" } : kw_business], "postprocess": first },
|
|
1133
|
+
{ "name": "eodKeyword", "symbols": [lexer.has("kw_eod") ? { type: "kw_eod" } : kw_eod], "postprocess": first },
|
|
1134
|
+
{ "name": "cobKeyword", "symbols": [lexer.has("kw_cob") ? { type: "kw_cob" } : kw_cob], "postprocess": first },
|
|
1135
|
+
{ "name": "closeKeyword", "symbols": [lexer.has("kw_close") ? { type: "kw_close" } : kw_close], "postprocess": first },
|
|
956
1136
|
{ "name": "_$ebnf$1", "symbols": [] },
|
|
957
1137
|
{ "name": "_$ebnf$1", "symbols": ["_$ebnf$1", lexer.has("ws") ? { type: "ws" } : ws], "postprocess": (d) => d[0].concat([d[1]]) },
|
|
958
1138
|
{ "name": "_", "symbols": ["_$ebnf$1"], "postprocess": nuller }
|
|
@@ -1210,6 +1390,114 @@ function convertMonthDay(node, opts) {
|
|
|
1210
1390
|
}
|
|
1211
1391
|
return date;
|
|
1212
1392
|
}
|
|
1393
|
+
function convertOrdinalWeekdayOfMonth(node, opts) {
|
|
1394
|
+
const ref = opts.referenceDate;
|
|
1395
|
+
const ordinal2 = node.ordinalWeekday;
|
|
1396
|
+
const weekdayName = node.weekday.toLowerCase();
|
|
1397
|
+
const weekdayNum = WEEKDAY_MAP[weekdayName] ?? 0;
|
|
1398
|
+
let month2;
|
|
1399
|
+
let year;
|
|
1400
|
+
if (node.monthFromRef) {
|
|
1401
|
+
month2 = ref.getUTCMonth();
|
|
1402
|
+
year = ref.getUTCFullYear();
|
|
1403
|
+
} else if (node.nextMonth) {
|
|
1404
|
+
month2 = ref.getUTCMonth() + 1;
|
|
1405
|
+
year = ref.getUTCFullYear();
|
|
1406
|
+
if (month2 > 11) {
|
|
1407
|
+
month2 = 0;
|
|
1408
|
+
year++;
|
|
1409
|
+
}
|
|
1410
|
+
} else {
|
|
1411
|
+
month2 = typeof node.month === "number" ? node.month - 1 : ref.getUTCMonth();
|
|
1412
|
+
year = ref.getUTCFullYear();
|
|
1413
|
+
if (month2 < ref.getUTCMonth()) {
|
|
1414
|
+
year++;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
if (ordinal2 === -1) {
|
|
1418
|
+
const lastDay2 = new Date(Date.UTC(year, month2 + 1, 0));
|
|
1419
|
+
let day2 = lastDay2.getUTCDate();
|
|
1420
|
+
let date2 = new Date(Date.UTC(year, month2, day2));
|
|
1421
|
+
while (date2.getUTCDay() !== weekdayNum) {
|
|
1422
|
+
day2--;
|
|
1423
|
+
date2 = new Date(Date.UTC(year, month2, day2));
|
|
1424
|
+
}
|
|
1425
|
+
return date2;
|
|
1426
|
+
}
|
|
1427
|
+
let count = 0;
|
|
1428
|
+
for (let day2 = 1; day2 <= 31; day2++) {
|
|
1429
|
+
const date2 = new Date(Date.UTC(year, month2, day2));
|
|
1430
|
+
if (date2.getUTCMonth() !== month2) {
|
|
1431
|
+
break;
|
|
1432
|
+
}
|
|
1433
|
+
if (date2.getUTCDay() === weekdayNum) {
|
|
1434
|
+
count++;
|
|
1435
|
+
if (count === ordinal2) {
|
|
1436
|
+
return date2;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
const lastDay = new Date(Date.UTC(year, month2 + 1, 0));
|
|
1441
|
+
let day = lastDay.getUTCDate();
|
|
1442
|
+
let date = new Date(Date.UTC(year, month2, day));
|
|
1443
|
+
while (date.getUTCDay() !== weekdayNum) {
|
|
1444
|
+
day--;
|
|
1445
|
+
date = new Date(Date.UTC(year, month2, day));
|
|
1446
|
+
}
|
|
1447
|
+
return date;
|
|
1448
|
+
}
|
|
1449
|
+
function convertLastDayOfMonth(node, opts) {
|
|
1450
|
+
const ref = opts.referenceDate;
|
|
1451
|
+
let month2;
|
|
1452
|
+
let year;
|
|
1453
|
+
if (node.monthFromRef) {
|
|
1454
|
+
month2 = ref.getUTCMonth();
|
|
1455
|
+
year = ref.getUTCFullYear();
|
|
1456
|
+
} else if (node.nextMonth) {
|
|
1457
|
+
month2 = ref.getUTCMonth() + 1;
|
|
1458
|
+
year = ref.getUTCFullYear();
|
|
1459
|
+
if (month2 > 11) {
|
|
1460
|
+
month2 = 0;
|
|
1461
|
+
year++;
|
|
1462
|
+
}
|
|
1463
|
+
} else {
|
|
1464
|
+
month2 = typeof node.month === "number" ? node.month - 1 : ref.getUTCMonth();
|
|
1465
|
+
year = ref.getUTCFullYear();
|
|
1466
|
+
if (month2 < ref.getUTCMonth()) {
|
|
1467
|
+
year++;
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
return new Date(Date.UTC(year, month2 + 1, 0));
|
|
1471
|
+
}
|
|
1472
|
+
function convertDayOnly(node, opts) {
|
|
1473
|
+
const ref = opts.referenceDate;
|
|
1474
|
+
const day = node.day;
|
|
1475
|
+
const refDay = ref.getUTCDate();
|
|
1476
|
+
const refMonth = ref.getUTCMonth();
|
|
1477
|
+
const refYear = ref.getUTCFullYear();
|
|
1478
|
+
let month2 = refMonth;
|
|
1479
|
+
let year = refYear;
|
|
1480
|
+
if (day < refDay) {
|
|
1481
|
+
month2 = refMonth + 1;
|
|
1482
|
+
if (month2 > 11) {
|
|
1483
|
+
month2 = 0;
|
|
1484
|
+
year++;
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
let date = new Date(Date.UTC(year, month2, day));
|
|
1488
|
+
while (date.getUTCDate() !== day) {
|
|
1489
|
+
month2++;
|
|
1490
|
+
if (month2 > 11) {
|
|
1491
|
+
month2 = 0;
|
|
1492
|
+
year++;
|
|
1493
|
+
}
|
|
1494
|
+
date = new Date(Date.UTC(year, month2, day));
|
|
1495
|
+
}
|
|
1496
|
+
if (node.time) {
|
|
1497
|
+
applyTime(date, node.time);
|
|
1498
|
+
}
|
|
1499
|
+
return date;
|
|
1500
|
+
}
|
|
1213
1501
|
function convertRelativePeriod(node, opts) {
|
|
1214
1502
|
const ref = opts.referenceDate;
|
|
1215
1503
|
const period = node.period.toLowerCase();
|
|
@@ -1269,6 +1557,9 @@ function convertDateNode(node, opts) {
|
|
|
1269
1557
|
if (node.timeOnly && node.time) {
|
|
1270
1558
|
return convertTimeOnly(node, opts);
|
|
1271
1559
|
}
|
|
1560
|
+
if (node.ordinalWeekday !== void 0 && node.weekday !== void 0) {
|
|
1561
|
+
return convertOrdinalWeekdayOfMonth(node, opts);
|
|
1562
|
+
}
|
|
1272
1563
|
if (node.weekday) {
|
|
1273
1564
|
return convertWeekday(node, opts);
|
|
1274
1565
|
}
|
|
@@ -1278,6 +1569,23 @@ function convertDateNode(node, opts) {
|
|
|
1278
1569
|
if (node.month !== void 0 && node.day !== void 0) {
|
|
1279
1570
|
return convertMonthDay(node, opts);
|
|
1280
1571
|
}
|
|
1572
|
+
if (node.dayOnly && node.day !== void 0) {
|
|
1573
|
+
return convertDayOnly(node, opts);
|
|
1574
|
+
}
|
|
1575
|
+
if (node.lastDayOfMonth) {
|
|
1576
|
+
return convertLastDayOfMonth(node, opts);
|
|
1577
|
+
}
|
|
1578
|
+
if (node.dayOfMonth && node.nextMonth) {
|
|
1579
|
+
const ref = opts.referenceDate;
|
|
1580
|
+
let month2 = ref.getUTCMonth() + 1;
|
|
1581
|
+
let year = ref.getUTCFullYear();
|
|
1582
|
+
if (month2 > 11) {
|
|
1583
|
+
month2 = 0;
|
|
1584
|
+
year++;
|
|
1585
|
+
}
|
|
1586
|
+
const day = node.ordinalWeekday || 1;
|
|
1587
|
+
return new Date(Date.UTC(year, month2, day));
|
|
1588
|
+
}
|
|
1281
1589
|
if (node.relative && node.period) {
|
|
1282
1590
|
return convertRelativePeriod(node, opts);
|
|
1283
1591
|
}
|
|
@@ -1349,7 +1657,7 @@ function getHalfDates(half2, year, fiscalYearStart) {
|
|
|
1349
1657
|
const start = new Date(Date.UTC(startYear, halfStartMonth, 1));
|
|
1350
1658
|
const endMonth = (halfStartMonth + 6) % 12;
|
|
1351
1659
|
let endYear = startYear;
|
|
1352
|
-
if (endMonth
|
|
1660
|
+
if (endMonth <= halfStartMonth) {
|
|
1353
1661
|
endYear++;
|
|
1354
1662
|
}
|
|
1355
1663
|
const end = new Date(Date.UTC(endYear, endMonth, 0));
|
|
@@ -1422,8 +1730,115 @@ function getModifiedPeriod(start, end, modifier) {
|
|
|
1422
1730
|
}
|
|
1423
1731
|
|
|
1424
1732
|
// src/converters/fuzzy.ts
|
|
1733
|
+
function getWeekendDates(ref, relative, opts) {
|
|
1734
|
+
const currentDay = ref.getUTCDay();
|
|
1735
|
+
const saturdayOffset = (6 - currentDay + 7) % 7;
|
|
1736
|
+
let saturday = new Date(
|
|
1737
|
+
Date.UTC(
|
|
1738
|
+
ref.getUTCFullYear(),
|
|
1739
|
+
ref.getUTCMonth(),
|
|
1740
|
+
ref.getUTCDate() + saturdayOffset
|
|
1741
|
+
)
|
|
1742
|
+
);
|
|
1743
|
+
if (relative === "next") {
|
|
1744
|
+
saturday = new Date(saturday.getTime() + MS_PER_WEEK);
|
|
1745
|
+
} else if (relative === "last") {
|
|
1746
|
+
if (currentDay === 6 || currentDay === 0) {
|
|
1747
|
+
saturday = new Date(saturday.getTime() - MS_PER_WEEK);
|
|
1748
|
+
}
|
|
1749
|
+
saturday = new Date(saturday.getTime() - MS_PER_WEEK);
|
|
1750
|
+
}
|
|
1751
|
+
const sunday = new Date(saturday.getTime() + MS_PER_DAY);
|
|
1752
|
+
const sundayEnd = new Date(
|
|
1753
|
+
Date.UTC(
|
|
1754
|
+
sunday.getUTCFullYear(),
|
|
1755
|
+
sunday.getUTCMonth(),
|
|
1756
|
+
sunday.getUTCDate(),
|
|
1757
|
+
23,
|
|
1758
|
+
59
|
|
1759
|
+
)
|
|
1760
|
+
);
|
|
1761
|
+
return { start: saturday, end: sundayEnd };
|
|
1762
|
+
}
|
|
1763
|
+
function getNightDates(ref, relative, weekday2) {
|
|
1764
|
+
let baseDate = new Date(ref);
|
|
1765
|
+
if (relative === "last") {
|
|
1766
|
+
baseDate = new Date(
|
|
1767
|
+
Date.UTC(
|
|
1768
|
+
ref.getUTCFullYear(),
|
|
1769
|
+
ref.getUTCMonth(),
|
|
1770
|
+
ref.getUTCDate() - 1
|
|
1771
|
+
)
|
|
1772
|
+
);
|
|
1773
|
+
} else if (relative === "tomorrow") {
|
|
1774
|
+
baseDate = new Date(
|
|
1775
|
+
Date.UTC(
|
|
1776
|
+
ref.getUTCFullYear(),
|
|
1777
|
+
ref.getUTCMonth(),
|
|
1778
|
+
ref.getUTCDate() + 1
|
|
1779
|
+
)
|
|
1780
|
+
);
|
|
1781
|
+
} else if (weekday2) {
|
|
1782
|
+
const targetDay = WEEKDAY_MAP[weekday2.toLowerCase()];
|
|
1783
|
+
if (targetDay !== void 0) {
|
|
1784
|
+
const currentDay = ref.getUTCDay();
|
|
1785
|
+
let daysToAdd = (targetDay - currentDay + 7) % 7;
|
|
1786
|
+
if (daysToAdd === 0) {
|
|
1787
|
+
daysToAdd = 7;
|
|
1788
|
+
}
|
|
1789
|
+
baseDate = new Date(
|
|
1790
|
+
Date.UTC(
|
|
1791
|
+
ref.getUTCFullYear(),
|
|
1792
|
+
ref.getUTCMonth(),
|
|
1793
|
+
ref.getUTCDate() + daysToAdd
|
|
1794
|
+
)
|
|
1795
|
+
);
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
const start = new Date(
|
|
1799
|
+
Date.UTC(
|
|
1800
|
+
baseDate.getUTCFullYear(),
|
|
1801
|
+
baseDate.getUTCMonth(),
|
|
1802
|
+
baseDate.getUTCDate(),
|
|
1803
|
+
18,
|
|
1804
|
+
0
|
|
1805
|
+
)
|
|
1806
|
+
);
|
|
1807
|
+
const end = new Date(
|
|
1808
|
+
Date.UTC(
|
|
1809
|
+
baseDate.getUTCFullYear(),
|
|
1810
|
+
baseDate.getUTCMonth(),
|
|
1811
|
+
baseDate.getUTCDate(),
|
|
1812
|
+
23,
|
|
1813
|
+
59
|
|
1814
|
+
)
|
|
1815
|
+
);
|
|
1816
|
+
return { start, end };
|
|
1817
|
+
}
|
|
1425
1818
|
function getBasePeriodDates(node, opts, year) {
|
|
1426
1819
|
const ref = opts.referenceDate;
|
|
1820
|
+
if (node.period === "weekend") {
|
|
1821
|
+
return getWeekendDates(ref, node.relative || "this", opts);
|
|
1822
|
+
}
|
|
1823
|
+
if (node.period === "tonight") {
|
|
1824
|
+
return getNightDates(ref, void 0, void 0);
|
|
1825
|
+
}
|
|
1826
|
+
if (node.period === "night") {
|
|
1827
|
+
return getNightDates(ref, node.relative, node.weekday);
|
|
1828
|
+
}
|
|
1829
|
+
if (node.period === "fortnight") {
|
|
1830
|
+
const count = node.count || 1;
|
|
1831
|
+
const relative = node.relative;
|
|
1832
|
+
const twoWeeks = 14 * MS_PER_DAY;
|
|
1833
|
+
if (relative === "last") {
|
|
1834
|
+
const end2 = new Date(ref);
|
|
1835
|
+
const start2 = new Date(ref.getTime() - twoWeeks);
|
|
1836
|
+
return { start: start2, end: end2 };
|
|
1837
|
+
}
|
|
1838
|
+
const start = new Date(ref);
|
|
1839
|
+
const end = new Date(ref.getTime() + count * twoWeeks);
|
|
1840
|
+
return { start, end };
|
|
1841
|
+
}
|
|
1427
1842
|
if (node.period === "quarter" && node.quarter) {
|
|
1428
1843
|
return getQuarterDates(
|
|
1429
1844
|
node.quarter,
|
|
@@ -1463,6 +1878,42 @@ function getBasePeriodDates(node, opts, year) {
|
|
|
1463
1878
|
const end = new Date(start.getTime() + 6 * MS_PER_DAY);
|
|
1464
1879
|
return { start, end };
|
|
1465
1880
|
}
|
|
1881
|
+
if (node.period === "weekNumber" && node.weekNumber !== void 0) {
|
|
1882
|
+
const weekNum = node.weekNumber;
|
|
1883
|
+
const targetYear = node.year ?? ref.getUTCFullYear();
|
|
1884
|
+
const weekStart = opts.weekStartsOn === "monday" ? 1 : 0;
|
|
1885
|
+
const jan1 = new Date(Date.UTC(targetYear, 0, 1));
|
|
1886
|
+
const jan1Day = jan1.getUTCDay();
|
|
1887
|
+
const daysToFirstWeekStart = (weekStart - jan1Day + 7) % 7;
|
|
1888
|
+
const firstWeekStart = new Date(jan1.getTime() + daysToFirstWeekStart * MS_PER_DAY);
|
|
1889
|
+
const start = new Date(firstWeekStart.getTime() + (weekNum - 1) * MS_PER_WEEK);
|
|
1890
|
+
const end = new Date(start.getTime() + 6 * MS_PER_DAY);
|
|
1891
|
+
return { start, end };
|
|
1892
|
+
}
|
|
1893
|
+
if (node.period === "weekOf" && node.baseDate) {
|
|
1894
|
+
const baseDate = node.baseDate;
|
|
1895
|
+
let targetDate;
|
|
1896
|
+
if (baseDate.month !== void 0 && baseDate.day !== void 0) {
|
|
1897
|
+
const month2 = typeof baseDate.month === "number" ? baseDate.month - 1 : 0;
|
|
1898
|
+
const day = baseDate.day;
|
|
1899
|
+
const targetYear = baseDate.year ?? ref.getUTCFullYear();
|
|
1900
|
+
targetDate = new Date(Date.UTC(targetYear, month2, day));
|
|
1901
|
+
} else {
|
|
1902
|
+
targetDate = ref;
|
|
1903
|
+
}
|
|
1904
|
+
const weekStart = opts.weekStartsOn === "monday" ? 1 : 0;
|
|
1905
|
+
const currentDay = targetDate.getUTCDay();
|
|
1906
|
+
const daysFromStart = (currentDay - weekStart + 7) % 7;
|
|
1907
|
+
const start = new Date(
|
|
1908
|
+
Date.UTC(
|
|
1909
|
+
targetDate.getUTCFullYear(),
|
|
1910
|
+
targetDate.getUTCMonth(),
|
|
1911
|
+
targetDate.getUTCDate() - daysFromStart
|
|
1912
|
+
)
|
|
1913
|
+
);
|
|
1914
|
+
const end = new Date(start.getTime() + 6 * MS_PER_DAY);
|
|
1915
|
+
return { start, end };
|
|
1916
|
+
}
|
|
1466
1917
|
if (node.period === "day") {
|
|
1467
1918
|
const start = new Date(
|
|
1468
1919
|
Date.UTC(ref.getUTCFullYear(), ref.getUTCMonth(), ref.getUTCDate())
|
|
@@ -1586,7 +2037,7 @@ function convertASTToResult(ast, opts, originalInput) {
|
|
|
1586
2037
|
end = new Date(Date.UTC(year, month2 + 1, 0));
|
|
1587
2038
|
}
|
|
1588
2039
|
if (endNode.yearOnly) {
|
|
1589
|
-
const year = endNode.year;
|
|
2040
|
+
const year = endNode.year ?? opts.referenceDate.getUTCFullYear();
|
|
1590
2041
|
end = new Date(Date.UTC(year, 11, 31));
|
|
1591
2042
|
}
|
|
1592
2043
|
} else if (endNode.nodeType === "fuzzy") {
|
|
@@ -1617,6 +2068,7 @@ function convertASTToResult(ast, opts, originalInput) {
|
|
|
1617
2068
|
case "fuzzy": {
|
|
1618
2069
|
const { start, end } = convertFuzzyNode(expression, opts);
|
|
1619
2070
|
const mod = expression.modifier;
|
|
2071
|
+
const period = expression.period;
|
|
1620
2072
|
if (mod === "start" || mod === "beginning") {
|
|
1621
2073
|
const periodDates = convertFuzzyNodeWithoutModifier(expression, opts);
|
|
1622
2074
|
return { type: "date", date: periodDates.start, title };
|
|
@@ -1625,6 +2077,10 @@ function convertASTToResult(ast, opts, originalInput) {
|
|
|
1625
2077
|
const periodDates = convertFuzzyNodeWithoutModifier(expression, opts);
|
|
1626
2078
|
return { type: "date", date: periodDates.end, title };
|
|
1627
2079
|
}
|
|
2080
|
+
if (period === "weekend" || period === "night" || period === "tonight" || period === "fortnight" || period === "weekNumber" || period === "weekOf") {
|
|
2081
|
+
const duration = end.getTime() - start.getTime();
|
|
2082
|
+
return { type: "span", start, end, duration, title };
|
|
2083
|
+
}
|
|
1628
2084
|
return { type: "fuzzy", start, end, approximate: true, title };
|
|
1629
2085
|
}
|
|
1630
2086
|
case "relative": {
|
|
@@ -1641,6 +2097,91 @@ function convertASTToResult(ast, opts, originalInput) {
|
|
|
1641
2097
|
}
|
|
1642
2098
|
return { type: "span", start, end, duration, title };
|
|
1643
2099
|
}
|
|
2100
|
+
case "relativeDate": {
|
|
2101
|
+
const durationNode = expression.duration;
|
|
2102
|
+
const baseNode = expression.baseDate;
|
|
2103
|
+
const timeSpec = expression.time;
|
|
2104
|
+
let baseDate;
|
|
2105
|
+
if (baseNode) {
|
|
2106
|
+
baseDate = convertDateNode(baseNode, opts);
|
|
2107
|
+
} else {
|
|
2108
|
+
baseDate = new Date(opts.referenceDate);
|
|
2109
|
+
}
|
|
2110
|
+
const durationValue = durationNode.value;
|
|
2111
|
+
const durationUnit = durationNode.unit;
|
|
2112
|
+
const direction = expression.direction === "past" ? -1 : 1;
|
|
2113
|
+
let resultDate;
|
|
2114
|
+
if (durationUnit === "month") {
|
|
2115
|
+
resultDate = new Date(
|
|
2116
|
+
Date.UTC(
|
|
2117
|
+
baseDate.getUTCFullYear(),
|
|
2118
|
+
baseDate.getUTCMonth() + direction * durationValue,
|
|
2119
|
+
baseDate.getUTCDate(),
|
|
2120
|
+
baseDate.getUTCHours(),
|
|
2121
|
+
baseDate.getUTCMinutes()
|
|
2122
|
+
)
|
|
2123
|
+
);
|
|
2124
|
+
} else if (durationUnit === "year") {
|
|
2125
|
+
resultDate = new Date(
|
|
2126
|
+
Date.UTC(
|
|
2127
|
+
baseDate.getUTCFullYear() + direction * durationValue,
|
|
2128
|
+
baseDate.getUTCMonth(),
|
|
2129
|
+
baseDate.getUTCDate(),
|
|
2130
|
+
baseDate.getUTCHours(),
|
|
2131
|
+
baseDate.getUTCMinutes()
|
|
2132
|
+
)
|
|
2133
|
+
);
|
|
2134
|
+
} else if (durationUnit === "businessDay" || durationUnit === "businessday") {
|
|
2135
|
+
resultDate = new Date(Date.UTC(baseDate.getUTCFullYear(), baseDate.getUTCMonth(), baseDate.getUTCDate()));
|
|
2136
|
+
let daysToAdd = durationValue;
|
|
2137
|
+
while (daysToAdd > 0) {
|
|
2138
|
+
resultDate.setUTCDate(resultDate.getUTCDate() + direction);
|
|
2139
|
+
const dayOfWeek = resultDate.getUTCDay();
|
|
2140
|
+
if (dayOfWeek !== 0 && dayOfWeek !== 6) {
|
|
2141
|
+
daysToAdd--;
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
} else {
|
|
2145
|
+
const durationMs = convertDurationNode(durationNode);
|
|
2146
|
+
resultDate = new Date(baseDate.getTime() + direction * durationMs);
|
|
2147
|
+
}
|
|
2148
|
+
if (timeSpec) {
|
|
2149
|
+
if ("special" in timeSpec) {
|
|
2150
|
+
if (timeSpec.special === "noon") {
|
|
2151
|
+
resultDate = new Date(
|
|
2152
|
+
Date.UTC(
|
|
2153
|
+
resultDate.getUTCFullYear(),
|
|
2154
|
+
resultDate.getUTCMonth(),
|
|
2155
|
+
resultDate.getUTCDate(),
|
|
2156
|
+
12,
|
|
2157
|
+
0
|
|
2158
|
+
)
|
|
2159
|
+
);
|
|
2160
|
+
} else if (timeSpec.special === "midnight") {
|
|
2161
|
+
resultDate = new Date(
|
|
2162
|
+
Date.UTC(
|
|
2163
|
+
resultDate.getUTCFullYear(),
|
|
2164
|
+
resultDate.getUTCMonth(),
|
|
2165
|
+
resultDate.getUTCDate(),
|
|
2166
|
+
0,
|
|
2167
|
+
0
|
|
2168
|
+
)
|
|
2169
|
+
);
|
|
2170
|
+
}
|
|
2171
|
+
} else {
|
|
2172
|
+
resultDate = new Date(
|
|
2173
|
+
Date.UTC(
|
|
2174
|
+
resultDate.getUTCFullYear(),
|
|
2175
|
+
resultDate.getUTCMonth(),
|
|
2176
|
+
resultDate.getUTCDate(),
|
|
2177
|
+
timeSpec.hour,
|
|
2178
|
+
timeSpec.minute
|
|
2179
|
+
)
|
|
2180
|
+
);
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
return { type: "date", date: resultDate, title };
|
|
2184
|
+
}
|
|
1644
2185
|
default:
|
|
1645
2186
|
return null;
|
|
1646
2187
|
}
|
|
@@ -1663,13 +2204,13 @@ function stripUnmatchedPunctuation(input) {
|
|
|
1663
2204
|
openParens = (result.match(/\(/g) || []).length;
|
|
1664
2205
|
closeParens = (result.match(/\)/g) || []).length;
|
|
1665
2206
|
while (openParens > closeParens) {
|
|
1666
|
-
result = result.replace(
|
|
2207
|
+
result = result.replace(/\(/, "");
|
|
1667
2208
|
openParens--;
|
|
1668
2209
|
}
|
|
1669
2210
|
openBrackets = (result.match(/\[/g) || []).length;
|
|
1670
2211
|
closeBrackets = (result.match(/]/g) || []).length;
|
|
1671
2212
|
while (openBrackets > closeBrackets) {
|
|
1672
|
-
result = result.replace(
|
|
2213
|
+
result = result.replace(/\[/, "");
|
|
1673
2214
|
openBrackets--;
|
|
1674
2215
|
}
|
|
1675
2216
|
return {
|