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.js
CHANGED
|
@@ -230,8 +230,21 @@ var lexer = moo.compile({
|
|
|
230
230
|
"sat",
|
|
231
231
|
"sun"
|
|
232
232
|
],
|
|
233
|
+
// Ago keyword for relative dates
|
|
234
|
+
kw_ago: ["ago"],
|
|
235
|
+
// Weekend and night keywords
|
|
236
|
+
kw_weekend: ["weekend"],
|
|
237
|
+
kw_tonight: ["tonight"],
|
|
238
|
+
kw_night: ["night"],
|
|
239
|
+
kw_fortnight: ["fortnight", "fortnights"],
|
|
233
240
|
// Other keywords
|
|
234
|
-
otherKeyword: ["fiscal", "fy", "daily", "weekly", "monthly", "yearly", "annually", "
|
|
241
|
+
otherKeyword: ["fiscal", "fy", "daily", "weekly", "monthly", "yearly", "annually", "hence", "later", "earlier"],
|
|
242
|
+
// Business keywords
|
|
243
|
+
kw_business: ["business"],
|
|
244
|
+
// EOD/COB keywords
|
|
245
|
+
kw_eod: ["eod"],
|
|
246
|
+
kw_cob: ["cob"],
|
|
247
|
+
kw_close: ["close"]
|
|
235
248
|
})
|
|
236
249
|
// Keywords are matched against lowercase input
|
|
237
250
|
},
|
|
@@ -284,6 +297,13 @@ var makeRelative = (direction, duration) => ({
|
|
|
284
297
|
direction,
|
|
285
298
|
duration
|
|
286
299
|
});
|
|
300
|
+
var makeRelativeDate = (direction, duration, baseDate, time2) => ({
|
|
301
|
+
nodeType: "relativeDate",
|
|
302
|
+
direction,
|
|
303
|
+
duration,
|
|
304
|
+
baseDate,
|
|
305
|
+
time: time2
|
|
306
|
+
});
|
|
287
307
|
var makeTitled = (title, expression, titleStart, titleEnd) => ({
|
|
288
308
|
nodeType: "titled",
|
|
289
309
|
title: title.trim(),
|
|
@@ -519,10 +539,14 @@ var grammar = {
|
|
|
519
539
|
{ "name": "expression", "symbols": ["range"], "postprocess": first },
|
|
520
540
|
{ "name": "expression", "symbols": ["span"], "postprocess": first },
|
|
521
541
|
{ "name": "expression", "symbols": ["relative"], "postprocess": first },
|
|
542
|
+
{ "name": "expression", "symbols": ["relativeDate"], "postprocess": first },
|
|
543
|
+
{ "name": "expression", "symbols": ["lastDayOfMonthExpr"], "postprocess": first },
|
|
544
|
+
{ "name": "expression", "symbols": ["date"], "postprocess": first },
|
|
522
545
|
{ "name": "expression", "symbols": ["fuzzy"], "postprocess": first },
|
|
523
546
|
{ "name": "expression", "symbols": ["forDuration"], "postprocess": first },
|
|
524
547
|
{ "name": "expression", "symbols": ["duration"], "postprocess": first },
|
|
525
|
-
{ "name": "
|
|
548
|
+
{ "name": "lastDayOfMonthExpr", "symbols": ["lastRelative", "_", "dayUnit", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ month: d[6], lastDayOfMonth: true }) },
|
|
549
|
+
{ "name": "lastDayOfMonthExpr", "symbols": ["lastRelative", "_", "dayUnit", "_", "ofConnector", "_", "theConnector", "_", "monthUnit"], "postprocess": (d) => makeDate({ lastDayOfMonth: true, monthFromRef: true }) },
|
|
526
550
|
{ "name": "forDuration", "symbols": ["forConnector", "_", "duration"], "postprocess": (d) => d[2] },
|
|
527
551
|
{ "name": "range", "symbols": ["date", "_", "toConnector", "_", "date"], "postprocess": (d) => makeRange(d[0], d[4]) },
|
|
528
552
|
{ "name": "range", "symbols": ["fromConnector", "_", "date", "_", "toConnector", "_", "date"], "postprocess": (d) => makeRange(d[2], d[6]) },
|
|
@@ -604,6 +628,44 @@ var grammar = {
|
|
|
604
628
|
{ "name": "relative", "symbols": ["inConnector", "_", "theConnector", "_", "pastRelative", "_", "unit"], "postprocess": (d) => makeRelative("past", makeDuration(1, d[6])) },
|
|
605
629
|
{ "name": "relative", "symbols": ["inConnector", "_", "theConnector", "_", "comingRelative", "_", "unit"], "postprocess": (d) => makeRelative("future", makeDuration(1, d[6])) },
|
|
606
630
|
{ "name": "relative", "symbols": ["inConnector", "_", "theConnector", "_", "upcomingRelative", "_", "unit"], "postprocess": (d) => makeRelative("future", makeDuration(1, d[6])) },
|
|
631
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", d[0]) },
|
|
632
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "agoConnector", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("past", d[0], void 0, d[6]) },
|
|
633
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "agoConnector", "_", "atConnector", "_", "timeWord"], "postprocess": (d) => makeRelativeDate("past", d[0], void 0, { special: d[6] }) },
|
|
634
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "duration"], "postprocess": (d) => makeRelativeDate("future", d[2]) },
|
|
635
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "duration", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("future", d[2], void 0, d[6]) },
|
|
636
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "duration", "_", "atConnector", "_", "timeWord"], "postprocess": (d) => makeRelativeDate("future", d[2], void 0, { special: d[6] }) },
|
|
637
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "now"], "postprocess": (d) => makeRelativeDate("future", d[0]) },
|
|
638
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "now", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("future", d[0], void 0, d[8]) },
|
|
639
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "now", "_", "atConnector", "_", "timeWord"], "postprocess": (d) => makeRelativeDate("future", d[0], void 0, { special: d[8] }) },
|
|
640
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "today"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "today" })) },
|
|
641
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "today", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "today" }), d[8]) },
|
|
642
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "tomorrow"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "tomorrow" })) },
|
|
643
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "tomorrow", "_", "atConnector", "_", "time"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "tomorrow" }), d[8]) },
|
|
644
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "fromConnector", "_", "yesterday"], "postprocess": (d) => makeRelativeDate("future", d[0], makeDate({ special: "yesterday" })) },
|
|
645
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "henceConnector"], "postprocess": (d) => makeRelativeDate("future", d[0]) },
|
|
646
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "laterConnector"], "postprocess": (d) => makeRelativeDate("future", d[0]) },
|
|
647
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "beforeConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("past", d[0], d[4]) },
|
|
648
|
+
{ "name": "relativeDate", "symbols": ["duration", "_", "afterConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("future", d[0], d[4]) },
|
|
649
|
+
{ "name": "relativeDate", "symbols": ["theConnector", "_", "dayUnit", "_", "beforeConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("past", makeDuration(1, "day"), d[6]) },
|
|
650
|
+
{ "name": "relativeDate", "symbols": ["theConnector", "_", "dayUnit", "_", "afterConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("future", makeDuration(1, "day"), d[6]) },
|
|
651
|
+
{ "name": "relativeDate", "symbols": ["dayUnit", "_", "beforeConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("past", makeDuration(1, "day"), d[4]) },
|
|
652
|
+
{ "name": "relativeDate", "symbols": ["dayUnit", "_", "afterConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("future", makeDuration(1, "day"), d[4]) },
|
|
653
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "unit", "_", "beforeConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("past", makeDuration(parseWordNumber(d[0]), d[2]), d[6]) },
|
|
654
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "unit", "_", "afterConnector", "_", "date"], "postprocess": (d) => makeRelativeDate("future", makeDuration(parseWordNumber(d[0]), d[2]), d[6]) },
|
|
655
|
+
{ "name": "relativeDate", "symbols": ["nextRelative", "_", "businessKeyword", "_", "dayOrDaysUnit"], "postprocess": (d) => makeRelativeDate("future", makeDuration(1, "businessDay")) },
|
|
656
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "number", "_", "businessKeyword", "_", "dayOrDaysUnit"], "postprocess": (d) => makeRelativeDate("future", makeDuration(d[2], "businessDay")) },
|
|
657
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "wordNumber", "_", "businessKeyword", "_", "dayOrDaysUnit"], "postprocess": (d) => makeRelativeDate("future", makeDuration(parseWordNumber(d[2]), "businessDay")) },
|
|
658
|
+
{ "name": "relativeDate", "symbols": ["number", "_", "businessKeyword", "_", "dayOrDaysUnit", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(d[0], "businessDay")) },
|
|
659
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "businessKeyword", "_", "dayOrDaysUnit", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(parseWordNumber(d[0]), "businessDay")) },
|
|
660
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "fortnightKeyword", "_", "fromConnector", "_", "now"], "postprocess": (d) => makeRelativeDate("future", makeDuration(parseWordNumber(d[0]) * 2, "week")) },
|
|
661
|
+
{ "name": "relativeDate", "symbols": ["number", "_", "fortnightKeyword", "_", "fromConnector", "_", "now"], "postprocess": (d) => makeRelativeDate("future", makeDuration(d[0] * 2, "week")) },
|
|
662
|
+
{ "name": "relativeDate", "symbols": ["fortnightKeyword", "_", "fromConnector", "_", "now"], "postprocess": (d) => makeRelativeDate("future", makeDuration(2, "week")) },
|
|
663
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "wordNumber", "_", "fortnightKeyword"], "postprocess": (d) => makeRelativeDate("future", makeDuration(parseWordNumber(d[2]) * 2, "week")) },
|
|
664
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "number", "_", "fortnightKeyword"], "postprocess": (d) => makeRelativeDate("future", makeDuration(d[2] * 2, "week")) },
|
|
665
|
+
{ "name": "relativeDate", "symbols": ["inConnector", "_", "fortnightKeyword"], "postprocess": (d) => makeRelativeDate("future", makeDuration(2, "week")) },
|
|
666
|
+
{ "name": "relativeDate", "symbols": ["wordNumber", "_", "fortnightKeyword", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(parseWordNumber(d[0]) * 2, "week")) },
|
|
667
|
+
{ "name": "relativeDate", "symbols": ["number", "_", "fortnightKeyword", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(d[0] * 2, "week")) },
|
|
668
|
+
{ "name": "relativeDate", "symbols": ["fortnightKeyword", "_", "agoConnector"], "postprocess": (d) => makeRelativeDate("past", makeDuration(2, "week")) },
|
|
607
669
|
{ "name": "fuzzy", "symbols": ["quarter"], "postprocess": (d) => makeFuzzy({ period: "quarter", quarter: parseQuarter(d[0].value) }) },
|
|
608
670
|
{ "name": "fuzzy", "symbols": ["quarter", "_", "year"], "postprocess": (d) => makeFuzzy({ period: "quarter", quarter: parseQuarter(d[0].value), year: d[2] }) },
|
|
609
671
|
{ "name": "fuzzy", "symbols": ["half"], "postprocess": (d) => makeFuzzy({ period: "half", half: parseHalf(d[0].value) }) },
|
|
@@ -686,8 +748,31 @@ var grammar = {
|
|
|
686
748
|
{ "name": "fuzzy", "symbols": ["lateModifier", "_", "thisRelative", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[4], modifier: "late", relative: "this" }) },
|
|
687
749
|
{ "name": "fuzzy", "symbols": ["beginningConnector", "_", "ofConnector", "_", "theConnector", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[6], modifier: "beginning" }) },
|
|
688
750
|
{ "name": "fuzzy", "symbols": ["middleConnector", "_", "ofConnector", "_", "theConnector", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[6], modifier: "middle" }) },
|
|
689
|
-
{ "name": "fuzzy", "symbols": ["lastRelative", "_", "unit", "_", "ofConnector", "_", "month"], "postprocess": (d
|
|
690
|
-
|
|
751
|
+
{ "name": "fuzzy", "symbols": ["lastRelative", "_", "unit", "_", "ofConnector", "_", "month"], "postprocess": (d, _, reject) => {
|
|
752
|
+
if (d[2].toLowerCase() === "day" || d[2].toLowerCase() === "days") return reject;
|
|
753
|
+
return makeFuzzy({ period: "month", month: d[6], modifier: "late" });
|
|
754
|
+
} },
|
|
755
|
+
{ "name": "fuzzy", "symbols": ["ordinalWord", "_", "unit", "_", "ofConnector", "_", "month"], "postprocess": (d, _, reject) => {
|
|
756
|
+
if (d[2].toLowerCase() === "day" || d[2].toLowerCase() === "days") return reject;
|
|
757
|
+
return makeFuzzy({ period: "month", month: d[6], modifier: parseOrdinalWord(d[0]) <= 2 ? "early" : parseOrdinalWord(d[0]) >= 4 ? "late" : "mid" });
|
|
758
|
+
} },
|
|
759
|
+
{ "name": "fuzzy", "symbols": ["weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "this" }) },
|
|
760
|
+
{ "name": "fuzzy", "symbols": ["theConnector", "_", "weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "this" }) },
|
|
761
|
+
{ "name": "fuzzy", "symbols": ["thisRelative", "_", "weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "this" }) },
|
|
762
|
+
{ "name": "fuzzy", "symbols": ["nextRelative", "_", "weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "next" }) },
|
|
763
|
+
{ "name": "fuzzy", "symbols": ["lastRelative", "_", "weekendKeyword"], "postprocess": (d) => makeFuzzy({ period: "weekend", relative: "last" }) },
|
|
764
|
+
{ "name": "fuzzy", "symbols": ["tonightKeyword"], "postprocess": (d) => makeFuzzy({ period: "tonight" }) },
|
|
765
|
+
{ "name": "fuzzy", "symbols": ["nightKeyword"], "postprocess": (d) => makeFuzzy({ period: "night" }) },
|
|
766
|
+
{ "name": "fuzzy", "symbols": ["lastRelative", "_", "nightKeyword"], "postprocess": (d) => makeFuzzy({ period: "night", relative: "last" }) },
|
|
767
|
+
{ "name": "fuzzy", "symbols": ["tomorrow", "_", "nightKeyword"], "postprocess": (d) => makeFuzzy({ period: "night", relative: "tomorrow" }) },
|
|
768
|
+
{ "name": "fuzzy", "symbols": ["weekday", "_", "nightKeyword"], "postprocess": (d) => makeFuzzy({ period: "night", weekday: d[0] }) },
|
|
769
|
+
{ "name": "fuzzy", "symbols": ["laterKeyword", "_", "today"], "postprocess": (d) => makeFuzzy({ period: "day", modifier: "later" }) },
|
|
770
|
+
{ "name": "fuzzy", "symbols": ["earlierKeyword", "_", "today"], "postprocess": (d) => makeFuzzy({ period: "day", modifier: "earlier" }) },
|
|
771
|
+
{ "name": "fuzzy", "symbols": ["laterKeyword", "_", "thisRelative", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[4], modifier: "later", relative: "this" }) },
|
|
772
|
+
{ "name": "fuzzy", "symbols": ["earlierKeyword", "_", "thisRelative", "_", "unit"], "postprocess": (d) => makeFuzzy({ period: d[4], modifier: "earlier", relative: "this" }) },
|
|
773
|
+
{ "name": "fuzzy", "symbols": ["weekKeyword", "_", "number"], "postprocess": (d) => makeFuzzy({ period: "weekNumber", weekNumber: d[2] }) },
|
|
774
|
+
{ "name": "fuzzy", "symbols": ["weekKeyword", "_", "number", "_", "year"], "postprocess": (d) => makeFuzzy({ period: "weekNumber", weekNumber: d[2], year: d[4] }) },
|
|
775
|
+
{ "name": "fuzzy", "symbols": ["theConnector", "_", "weekKeyword", "_", "ofConnector", "_", "date"], "postprocess": (d) => makeFuzzy({ period: "weekOf", baseDate: d[6] }) },
|
|
691
776
|
{ "name": "duration", "symbols": ["number", "_", "unit"], "postprocess": (d) => makeDuration(d[0], d[2]) },
|
|
692
777
|
{ "name": "duration", "symbols": ["wordNumber", "_", "unit"], "postprocess": (d) => makeDuration(parseWordNumber(d[0]), d[2]) },
|
|
693
778
|
{ "name": "duration", "symbols": ["abbreviatedDuration"], "postprocess": (d) => d[0] },
|
|
@@ -715,6 +800,7 @@ var grammar = {
|
|
|
715
800
|
return makeDuration(value, unitMap[match[2]]);
|
|
716
801
|
} },
|
|
717
802
|
{ "name": "date", "symbols": ["specialDay"], "postprocess": (d) => makeDate({ special: d[0] }) },
|
|
803
|
+
{ "name": "date", "symbols": ["ordinalWeekdayOfMonth"], "postprocess": first },
|
|
718
804
|
{ "name": "date", "symbols": ["relativeWeekday"], "postprocess": first },
|
|
719
805
|
{ "name": "date", "symbols": ["weekday"], "postprocess": (d) => makeDate({ weekday: d[0] }) },
|
|
720
806
|
{ "name": "date", "symbols": ["monthDayYear"], "postprocess": first },
|
|
@@ -729,6 +815,8 @@ var grammar = {
|
|
|
729
815
|
{ "name": "date", "symbols": ["monthOnly"], "postprocess": first },
|
|
730
816
|
{ "name": "date", "symbols": ["yearOnly"], "postprocess": first },
|
|
731
817
|
{ "name": "date", "symbols": ["timeOnly"], "postprocess": first },
|
|
818
|
+
{ "name": "date", "symbols": ["dayOnly"], "postprocess": first },
|
|
819
|
+
{ "name": "date", "symbols": ["eodCobDate"], "postprocess": first },
|
|
732
820
|
{ "name": "monthDayCompact", "symbols": [lexer.has("monthDayCompact") ? { type: "monthDayCompact" } : monthDayCompact], "postprocess": (d) => {
|
|
733
821
|
const parsed = parseMonthDayCompact(d[0].value);
|
|
734
822
|
return makeDate({ month: parsed.month, day: parsed.day });
|
|
@@ -745,6 +833,17 @@ var grammar = {
|
|
|
745
833
|
} },
|
|
746
834
|
{ "name": "timeOnly", "symbols": ["time"], "postprocess": (d) => makeDate({ time: d[0], timeOnly: true }) },
|
|
747
835
|
{ "name": "timeOnly", "symbols": ["timeWord"], "postprocess": (d) => makeDate({ time: { special: d[0] }, timeOnly: true }) },
|
|
836
|
+
{ "name": "dayOnly", "symbols": ["theConnector", "_", "dayNumber"], "postprocess": (d) => makeDate({ day: d[2], dayOnly: true }) },
|
|
837
|
+
{ "name": "dayOnly", "symbols": ["onConnector", "_", "theConnector", "_", "dayNumber"], "postprocess": (d) => makeDate({ day: d[4], dayOnly: true }) },
|
|
838
|
+
{ "name": "eodCobDate", "symbols": ["eodKeyword"], "postprocess": (d) => makeDate({ special: "today", time: { hour: 23, minute: 59 } }) },
|
|
839
|
+
{ "name": "eodCobDate", "symbols": ["cobKeyword"], "postprocess": (d) => makeDate({ special: "today", time: { hour: 17, minute: 0 } }) },
|
|
840
|
+
{ "name": "eodCobDate", "symbols": ["eodKeyword", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], time: { hour: 23, minute: 59 } }) },
|
|
841
|
+
{ "name": "eodCobDate", "symbols": ["cobKeyword", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], time: { hour: 17, minute: 0 } }) },
|
|
842
|
+
{ "name": "eodCobDate", "symbols": ["eodKeyword", "_", "specialDay"], "postprocess": (d) => makeDate({ special: d[2], time: { hour: 23, minute: 59 } }) },
|
|
843
|
+
{ "name": "eodCobDate", "symbols": ["cobKeyword", "_", "specialDay"], "postprocess": (d) => makeDate({ special: d[2], time: { hour: 17, minute: 0 } }) },
|
|
844
|
+
{ "name": "eodCobDate", "symbols": ["endConnector", "_", "ofConnector", "_", "dayUnit", "_", "specialDay"], "postprocess": (d) => makeDate({ special: d[6], time: { hour: 23, minute: 59 } }) },
|
|
845
|
+
{ "name": "eodCobDate", "symbols": ["closeKeyword", "_", "ofConnector", "_", "businessKeyword", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[6], time: { hour: 17, minute: 0 } }) },
|
|
846
|
+
{ "name": "eodCobDate", "symbols": ["closeKeyword", "_", "ofConnector", "_", "businessKeyword", "_", "specialDay"], "postprocess": (d) => makeDate({ special: d[6], time: { hour: 17, minute: 0 } }) },
|
|
748
847
|
{ "name": "specialDay", "symbols": ["today"], "postprocess": (d) => "today" },
|
|
749
848
|
{ "name": "specialDay", "symbols": ["tomorrow"], "postprocess": (d) => "tomorrow" },
|
|
750
849
|
{ "name": "specialDay", "symbols": ["yesterday"], "postprocess": (d) => "yesterday" },
|
|
@@ -753,7 +852,8 @@ var grammar = {
|
|
|
753
852
|
{ "name": "specialDay", "symbols": ["dayUnit", "_", "afterConnector", "_", "tomorrow"], "postprocess": (d) => "dayAfterTomorrow" },
|
|
754
853
|
{ "name": "specialDay", "symbols": ["theConnector", "_", "dayUnit", "_", "beforeConnector", "_", "yesterday"], "postprocess": (d) => "dayBeforeYesterday" },
|
|
755
854
|
{ "name": "specialDay", "symbols": ["dayUnit", "_", "beforeConnector", "_", "yesterday"], "postprocess": (d) => "dayBeforeYesterday" },
|
|
756
|
-
{ "name": "dayUnit", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d) => d[0].value === "day" ? d[0] :
|
|
855
|
+
{ "name": "dayUnit", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => d[0].value === "day" ? d[0] : reject },
|
|
856
|
+
{ "name": "dayOrDaysUnit", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => d[0].value === "day" || d[0].value === "days" ? d[0] : reject },
|
|
757
857
|
{ "name": "relativeWeekday", "symbols": ["nextRelative", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], relative: "next" }) },
|
|
758
858
|
{ "name": "relativeWeekday", "symbols": ["lastRelative", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], relative: "last" }) },
|
|
759
859
|
{ "name": "relativeWeekday", "symbols": ["thisRelative", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[2], relative: "this" }) },
|
|
@@ -768,6 +868,14 @@ var grammar = {
|
|
|
768
868
|
{ "name": "monthDay", "symbols": ["theConnector", "_", "dayNumber", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ month: d[6], day: d[2] }) },
|
|
769
869
|
{ "name": "monthDay", "symbols": ["month", "_", "ordinalWord"], "postprocess": (d) => makeDate({ month: d[0], day: parseOrdinalWord(d[2]) }) },
|
|
770
870
|
{ "name": "monthDay", "symbols": ["month", "_", "theConnector", "_", "dayNumber"], "postprocess": (d) => makeDate({ month: d[0], day: d[4] }) },
|
|
871
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["ordinalWord", "_", "weekday", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ ordinalWeekday: parseOrdinalWord(d[0]), weekday: d[2], month: d[6] }) },
|
|
872
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["lastRelative", "_", "weekday", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ ordinalWeekday: -1, weekday: d[2], month: d[6] }) },
|
|
873
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["ordinalWord", "_", "weekday", "_", "ofConnector", "_", "theConnector", "_", "monthUnit"], "postprocess": (d) => makeDate({ ordinalWeekday: parseOrdinalWord(d[0]), weekday: d[2], monthFromRef: true }) },
|
|
874
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["lastRelative", "_", "weekday", "_", "ofConnector", "_", "theConnector", "_", "monthUnit"], "postprocess": (d) => makeDate({ ordinalWeekday: -1, weekday: d[2], monthFromRef: true }) },
|
|
875
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["ordinalWord", "_", "dayUnit", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ month: d[6], day: parseOrdinalWord(d[0]) }) },
|
|
876
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["lastRelative", "_", "dayUnit", "_", "ofConnector", "_", "month"], "postprocess": (d) => makeDate({ month: d[6], day: -1, lastDayOfMonth: true }) },
|
|
877
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["lastRelative", "_", "dayUnit", "_", "ofConnector", "_", "theConnector", "_", "monthUnit"], "postprocess": (d) => makeDate({ lastDayOfMonth: true, monthFromRef: true }) },
|
|
878
|
+
{ "name": "ordinalWeekdayOfMonth", "symbols": ["ordinalWord", "_", "dayUnit", "_", "ofConnector", "_", "nextRelative", "_", "monthUnit"], "postprocess": (d) => makeDate({ ordinalWeekday: parseOrdinalWord(d[0]), dayOfMonth: true, nextMonth: true }) },
|
|
771
879
|
{ "name": "monthDayYear", "symbols": ["monthDay", "_", "year"], "postprocess": (d) => ({ ...d[0], year: d[2] }) },
|
|
772
880
|
{ "name": "monthDayYear", "symbols": ["monthDay", lexer.has("comma") ? { type: "comma" } : comma, "_", "year"], "postprocess": (d) => ({ ...d[0], year: d[3] }) },
|
|
773
881
|
{ "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) => {
|
|
@@ -789,6 +897,9 @@ var grammar = {
|
|
|
789
897
|
{ "name": "dateWithTime", "symbols": ["time", "_", "date"], "postprocess": (d) => ({ ...d[2], time: d[0] }) },
|
|
790
898
|
{ "name": "dateWithTime", "symbols": ["timeWord", "_", "date"], "postprocess": (d) => ({ ...d[2], time: { special: d[0] } }) },
|
|
791
899
|
{ "name": "dateWithTime", "symbols": ["date", "_", "time"], "postprocess": (d) => ({ ...d[0], time: d[2] }) },
|
|
900
|
+
{ "name": "dateWithTime", "symbols": ["timeWord", "_", "onConnector", "_", "date"], "postprocess": (d) => ({ ...d[4], time: { special: d[0] } }) },
|
|
901
|
+
{ "name": "dateWithTime", "symbols": ["timeWord", "_", "onConnector", "_", "weekday"], "postprocess": (d) => makeDate({ weekday: d[4], time: { special: d[0] } }) },
|
|
902
|
+
{ "name": "dateWithTime", "symbols": ["midnight", "_", "tonightKeyword"], "postprocess": (d) => makeDate({ special: "tonight", time: { special: "midnight" } }) },
|
|
792
903
|
{ "name": "complexDate", "symbols": ["nextRelative", "_", "unit", "_", "weekday", "_", "time"], "postprocess": (d) => makeDate({ relative: "next", period: d[2], weekday: d[4], time: d[6] }) },
|
|
793
904
|
{ "name": "complexDate", "symbols": ["nextRelative", "_", "unit", "_", "weekday"], "postprocess": (d) => makeDate({ relative: "next", period: d[2], weekday: d[4] }) },
|
|
794
905
|
{ "name": "complexDate", "symbols": ["lastRelative", "_", "unit", "_", "weekday", "_", "time"], "postprocess": (d) => makeDate({ relative: "last", period: d[2], weekday: d[4], time: d[6] }) },
|
|
@@ -825,6 +936,45 @@ var grammar = {
|
|
|
825
936
|
if (d[1].value === "am" && hour === 12) hour = 0;
|
|
826
937
|
return { hour, minute: 0 };
|
|
827
938
|
} },
|
|
939
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "pastConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4], minute: 15 }) },
|
|
940
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "pastConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
941
|
+
let hour = d[4];
|
|
942
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
943
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
944
|
+
return { hour, minute: 15 };
|
|
945
|
+
} },
|
|
946
|
+
{ "name": "time", "symbols": ["halfWord", "_", "pastConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4], minute: 30 }) },
|
|
947
|
+
{ "name": "time", "symbols": ["halfWord", "_", "pastConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
948
|
+
let hour = d[4];
|
|
949
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
950
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
951
|
+
return { hour, minute: 30 };
|
|
952
|
+
} },
|
|
953
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "toConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4] - 1, minute: 45 }) },
|
|
954
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "toConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
955
|
+
let hour = d[4];
|
|
956
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
957
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
958
|
+
return { hour: hour - 1, minute: 45 };
|
|
959
|
+
} },
|
|
960
|
+
{ "name": "time", "symbols": ["number", "_", "pastConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4], minute: d[0] }) },
|
|
961
|
+
{ "name": "time", "symbols": ["number", "_", "pastConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
962
|
+
let hour = d[4];
|
|
963
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
964
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
965
|
+
return { hour, minute: d[0] };
|
|
966
|
+
} },
|
|
967
|
+
{ "name": "time", "symbols": ["number", "_", "toConnector", "_", "hourNumber"], "postprocess": (d) => ({ hour: d[4] - 1, minute: 60 - d[0] }) },
|
|
968
|
+
{ "name": "time", "symbols": ["number", "_", "toConnector", "_", "hourNumber", lexer.has("ampm") ? { type: "ampm" } : ampm], "postprocess": (d) => {
|
|
969
|
+
let hour = d[4];
|
|
970
|
+
if (d[5].value === "pm" && hour !== 12) hour += 12;
|
|
971
|
+
if (d[5].value === "am" && hour === 12) hour = 0;
|
|
972
|
+
return { hour: hour - 1, minute: 60 - d[0] };
|
|
973
|
+
} },
|
|
974
|
+
{ "name": "time", "symbols": ["number", "_", "toConnector", "_", "noon"], "postprocess": (d) => ({ hour: 11, minute: 60 - d[0] }) },
|
|
975
|
+
{ "name": "time", "symbols": ["number", "_", "toConnector", "_", "midnight"], "postprocess": (d) => ({ hour: 23, minute: 60 - d[0] }) },
|
|
976
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "toConnector", "_", "noon"], "postprocess": (d) => ({ hour: 11, minute: 45 }) },
|
|
977
|
+
{ "name": "time", "symbols": ["quarterKeyword", "_", "toConnector", "_", "midnight"], "postprocess": (d) => ({ hour: 23, minute: 45 }) },
|
|
828
978
|
{ "name": "timeWord", "symbols": ["noon"], "postprocess": (d) => "noon" },
|
|
829
979
|
{ "name": "timeWord", "symbols": ["midnight"], "postprocess": (d) => "midnight" },
|
|
830
980
|
{ "name": "number", "symbols": [lexer.has("integer") ? { type: "integer" } : integer], "postprocess": (d) => parseInt(d[0].value, 10) },
|
|
@@ -861,6 +1011,11 @@ var grammar = {
|
|
|
861
1011
|
if (val === "year" || val === "years" || val === "yr" || val === "yrs") return val;
|
|
862
1012
|
return reject;
|
|
863
1013
|
} },
|
|
1014
|
+
{ "name": "monthUnit", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => {
|
|
1015
|
+
const val = d[0].value.toLowerCase();
|
|
1016
|
+
if (val === "month" || val === "months" || val === "mo" || val === "mos") return val;
|
|
1017
|
+
return reject;
|
|
1018
|
+
} },
|
|
864
1019
|
{ "name": "wordNumber", "symbols": [lexer.has("wordNumber") ? { type: "wordNumber" } : wordNumber], "postprocess": (d) => d[0].value },
|
|
865
1020
|
{ "name": "ordinalWord", "symbols": [lexer.has("ordinalWord") ? { type: "ordinalWord" } : ordinalWord], "postprocess": (d) => d[0].value },
|
|
866
1021
|
{ "name": "ordinalWord", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => {
|
|
@@ -897,6 +1052,9 @@ var grammar = {
|
|
|
897
1052
|
{ "name": "beginningConnector", "symbols": [lexer.has("kw_beginning") ? { type: "kw_beginning" } : kw_beginning], "postprocess": first },
|
|
898
1053
|
{ "name": "startConnector", "symbols": [lexer.has("kw_start") ? { type: "kw_start" } : kw_start], "postprocess": first },
|
|
899
1054
|
{ "name": "middleConnector", "symbols": [lexer.has("kw_middle") ? { type: "kw_middle" } : kw_middle], "postprocess": first },
|
|
1055
|
+
{ "name": "agoConnector", "symbols": [lexer.has("kw_ago") ? { type: "kw_ago" } : kw_ago], "postprocess": first },
|
|
1056
|
+
{ "name": "henceConnector", "symbols": [lexer.has("otherKeyword") ? { type: "otherKeyword" } : otherKeyword], "postprocess": (d, _, reject) => d[0].value === "hence" ? d[0] : reject },
|
|
1057
|
+
{ "name": "laterConnector", "symbols": [lexer.has("otherKeyword") ? { type: "otherKeyword" } : otherKeyword], "postprocess": (d, _, reject) => d[0].value === "later" ? d[0] : reject },
|
|
900
1058
|
{ "name": "earlyModifier", "symbols": [lexer.has("kw_early") ? { type: "kw_early" } : kw_early], "postprocess": first },
|
|
901
1059
|
{ "name": "midModifier", "symbols": [lexer.has("kw_mid") ? { type: "kw_mid" } : kw_mid], "postprocess": first },
|
|
902
1060
|
{ "name": "lateModifier", "symbols": [lexer.has("kw_late") ? { type: "kw_late" } : kw_late], "postprocess": first },
|
|
@@ -913,6 +1071,28 @@ var grammar = {
|
|
|
913
1071
|
{ "name": "now", "symbols": [lexer.has("kw_now") ? { type: "kw_now" } : kw_now], "postprocess": first },
|
|
914
1072
|
{ "name": "noon", "symbols": [lexer.has("kw_noon") ? { type: "kw_noon" } : kw_noon], "postprocess": first },
|
|
915
1073
|
{ "name": "midnight", "symbols": [lexer.has("kw_midnight") ? { type: "kw_midnight" } : kw_midnight], "postprocess": first },
|
|
1074
|
+
{ "name": "quarterKeyword", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => d[0].value === "quarter" ? d[0] : reject },
|
|
1075
|
+
{ "name": "hourNumber", "symbols": [lexer.has("integer") ? { type: "integer" } : integer], "postprocess": (d, _, reject) => {
|
|
1076
|
+
const val = parseInt(d[0].value, 10);
|
|
1077
|
+
if (val < 1 || val > 12) return reject;
|
|
1078
|
+
return val;
|
|
1079
|
+
} },
|
|
1080
|
+
{ "name": "pastConnector", "symbols": [lexer.has("kw_past") ? { type: "kw_past" } : kw_past], "postprocess": first },
|
|
1081
|
+
{ "name": "weekendKeyword", "symbols": [lexer.has("kw_weekend") ? { type: "kw_weekend" } : kw_weekend], "postprocess": first },
|
|
1082
|
+
{ "name": "tonightKeyword", "symbols": [lexer.has("kw_tonight") ? { type: "kw_tonight" } : kw_tonight], "postprocess": first },
|
|
1083
|
+
{ "name": "nightKeyword", "symbols": [lexer.has("kw_night") ? { type: "kw_night" } : kw_night], "postprocess": first },
|
|
1084
|
+
{ "name": "fortnightKeyword", "symbols": [lexer.has("kw_fortnight") ? { type: "kw_fortnight" } : kw_fortnight], "postprocess": first },
|
|
1085
|
+
{ "name": "laterKeyword", "symbols": [lexer.has("otherKeyword") ? { type: "otherKeyword" } : otherKeyword], "postprocess": (d, _, reject) => d[0].value === "later" ? d[0] : reject },
|
|
1086
|
+
{ "name": "earlierKeyword", "symbols": [lexer.has("otherKeyword") ? { type: "otherKeyword" } : otherKeyword], "postprocess": (d, _, reject) => d[0].value === "earlier" ? d[0] : reject },
|
|
1087
|
+
{ "name": "weekKeyword", "symbols": [lexer.has("unit") ? { type: "unit" } : unit], "postprocess": (d, _, reject) => {
|
|
1088
|
+
const val = d[0].value.toLowerCase();
|
|
1089
|
+
if (val === "week" || val === "weeks") return d[0];
|
|
1090
|
+
return reject;
|
|
1091
|
+
} },
|
|
1092
|
+
{ "name": "businessKeyword", "symbols": [lexer.has("kw_business") ? { type: "kw_business" } : kw_business], "postprocess": first },
|
|
1093
|
+
{ "name": "eodKeyword", "symbols": [lexer.has("kw_eod") ? { type: "kw_eod" } : kw_eod], "postprocess": first },
|
|
1094
|
+
{ "name": "cobKeyword", "symbols": [lexer.has("kw_cob") ? { type: "kw_cob" } : kw_cob], "postprocess": first },
|
|
1095
|
+
{ "name": "closeKeyword", "symbols": [lexer.has("kw_close") ? { type: "kw_close" } : kw_close], "postprocess": first },
|
|
916
1096
|
{ "name": "_$ebnf$1", "symbols": [] },
|
|
917
1097
|
{ "name": "_$ebnf$1", "symbols": ["_$ebnf$1", lexer.has("ws") ? { type: "ws" } : ws], "postprocess": (d) => d[0].concat([d[1]]) },
|
|
918
1098
|
{ "name": "_", "symbols": ["_$ebnf$1"], "postprocess": nuller }
|
|
@@ -1170,6 +1350,114 @@ function convertMonthDay(node, opts) {
|
|
|
1170
1350
|
}
|
|
1171
1351
|
return date;
|
|
1172
1352
|
}
|
|
1353
|
+
function convertOrdinalWeekdayOfMonth(node, opts) {
|
|
1354
|
+
const ref = opts.referenceDate;
|
|
1355
|
+
const ordinal2 = node.ordinalWeekday;
|
|
1356
|
+
const weekdayName = node.weekday.toLowerCase();
|
|
1357
|
+
const weekdayNum = WEEKDAY_MAP[weekdayName] ?? 0;
|
|
1358
|
+
let month2;
|
|
1359
|
+
let year;
|
|
1360
|
+
if (node.monthFromRef) {
|
|
1361
|
+
month2 = ref.getUTCMonth();
|
|
1362
|
+
year = ref.getUTCFullYear();
|
|
1363
|
+
} else if (node.nextMonth) {
|
|
1364
|
+
month2 = ref.getUTCMonth() + 1;
|
|
1365
|
+
year = ref.getUTCFullYear();
|
|
1366
|
+
if (month2 > 11) {
|
|
1367
|
+
month2 = 0;
|
|
1368
|
+
year++;
|
|
1369
|
+
}
|
|
1370
|
+
} else {
|
|
1371
|
+
month2 = typeof node.month === "number" ? node.month - 1 : ref.getUTCMonth();
|
|
1372
|
+
year = ref.getUTCFullYear();
|
|
1373
|
+
if (month2 < ref.getUTCMonth()) {
|
|
1374
|
+
year++;
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
if (ordinal2 === -1) {
|
|
1378
|
+
const lastDay2 = new Date(Date.UTC(year, month2 + 1, 0));
|
|
1379
|
+
let day2 = lastDay2.getUTCDate();
|
|
1380
|
+
let date2 = new Date(Date.UTC(year, month2, day2));
|
|
1381
|
+
while (date2.getUTCDay() !== weekdayNum) {
|
|
1382
|
+
day2--;
|
|
1383
|
+
date2 = new Date(Date.UTC(year, month2, day2));
|
|
1384
|
+
}
|
|
1385
|
+
return date2;
|
|
1386
|
+
}
|
|
1387
|
+
let count = 0;
|
|
1388
|
+
for (let day2 = 1; day2 <= 31; day2++) {
|
|
1389
|
+
const date2 = new Date(Date.UTC(year, month2, day2));
|
|
1390
|
+
if (date2.getUTCMonth() !== month2) {
|
|
1391
|
+
break;
|
|
1392
|
+
}
|
|
1393
|
+
if (date2.getUTCDay() === weekdayNum) {
|
|
1394
|
+
count++;
|
|
1395
|
+
if (count === ordinal2) {
|
|
1396
|
+
return date2;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
const lastDay = new Date(Date.UTC(year, month2 + 1, 0));
|
|
1401
|
+
let day = lastDay.getUTCDate();
|
|
1402
|
+
let date = new Date(Date.UTC(year, month2, day));
|
|
1403
|
+
while (date.getUTCDay() !== weekdayNum) {
|
|
1404
|
+
day--;
|
|
1405
|
+
date = new Date(Date.UTC(year, month2, day));
|
|
1406
|
+
}
|
|
1407
|
+
return date;
|
|
1408
|
+
}
|
|
1409
|
+
function convertLastDayOfMonth(node, opts) {
|
|
1410
|
+
const ref = opts.referenceDate;
|
|
1411
|
+
let month2;
|
|
1412
|
+
let year;
|
|
1413
|
+
if (node.monthFromRef) {
|
|
1414
|
+
month2 = ref.getUTCMonth();
|
|
1415
|
+
year = ref.getUTCFullYear();
|
|
1416
|
+
} else if (node.nextMonth) {
|
|
1417
|
+
month2 = ref.getUTCMonth() + 1;
|
|
1418
|
+
year = ref.getUTCFullYear();
|
|
1419
|
+
if (month2 > 11) {
|
|
1420
|
+
month2 = 0;
|
|
1421
|
+
year++;
|
|
1422
|
+
}
|
|
1423
|
+
} else {
|
|
1424
|
+
month2 = typeof node.month === "number" ? node.month - 1 : ref.getUTCMonth();
|
|
1425
|
+
year = ref.getUTCFullYear();
|
|
1426
|
+
if (month2 < ref.getUTCMonth()) {
|
|
1427
|
+
year++;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return new Date(Date.UTC(year, month2 + 1, 0));
|
|
1431
|
+
}
|
|
1432
|
+
function convertDayOnly(node, opts) {
|
|
1433
|
+
const ref = opts.referenceDate;
|
|
1434
|
+
const day = node.day;
|
|
1435
|
+
const refDay = ref.getUTCDate();
|
|
1436
|
+
const refMonth = ref.getUTCMonth();
|
|
1437
|
+
const refYear = ref.getUTCFullYear();
|
|
1438
|
+
let month2 = refMonth;
|
|
1439
|
+
let year = refYear;
|
|
1440
|
+
if (day < refDay) {
|
|
1441
|
+
month2 = refMonth + 1;
|
|
1442
|
+
if (month2 > 11) {
|
|
1443
|
+
month2 = 0;
|
|
1444
|
+
year++;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
let date = new Date(Date.UTC(year, month2, day));
|
|
1448
|
+
while (date.getUTCDate() !== day) {
|
|
1449
|
+
month2++;
|
|
1450
|
+
if (month2 > 11) {
|
|
1451
|
+
month2 = 0;
|
|
1452
|
+
year++;
|
|
1453
|
+
}
|
|
1454
|
+
date = new Date(Date.UTC(year, month2, day));
|
|
1455
|
+
}
|
|
1456
|
+
if (node.time) {
|
|
1457
|
+
applyTime(date, node.time);
|
|
1458
|
+
}
|
|
1459
|
+
return date;
|
|
1460
|
+
}
|
|
1173
1461
|
function convertRelativePeriod(node, opts) {
|
|
1174
1462
|
const ref = opts.referenceDate;
|
|
1175
1463
|
const period = node.period.toLowerCase();
|
|
@@ -1229,6 +1517,9 @@ function convertDateNode(node, opts) {
|
|
|
1229
1517
|
if (node.timeOnly && node.time) {
|
|
1230
1518
|
return convertTimeOnly(node, opts);
|
|
1231
1519
|
}
|
|
1520
|
+
if (node.ordinalWeekday !== void 0 && node.weekday !== void 0) {
|
|
1521
|
+
return convertOrdinalWeekdayOfMonth(node, opts);
|
|
1522
|
+
}
|
|
1232
1523
|
if (node.weekday) {
|
|
1233
1524
|
return convertWeekday(node, opts);
|
|
1234
1525
|
}
|
|
@@ -1238,6 +1529,23 @@ function convertDateNode(node, opts) {
|
|
|
1238
1529
|
if (node.month !== void 0 && node.day !== void 0) {
|
|
1239
1530
|
return convertMonthDay(node, opts);
|
|
1240
1531
|
}
|
|
1532
|
+
if (node.dayOnly && node.day !== void 0) {
|
|
1533
|
+
return convertDayOnly(node, opts);
|
|
1534
|
+
}
|
|
1535
|
+
if (node.lastDayOfMonth) {
|
|
1536
|
+
return convertLastDayOfMonth(node, opts);
|
|
1537
|
+
}
|
|
1538
|
+
if (node.dayOfMonth && node.nextMonth) {
|
|
1539
|
+
const ref = opts.referenceDate;
|
|
1540
|
+
let month2 = ref.getUTCMonth() + 1;
|
|
1541
|
+
let year = ref.getUTCFullYear();
|
|
1542
|
+
if (month2 > 11) {
|
|
1543
|
+
month2 = 0;
|
|
1544
|
+
year++;
|
|
1545
|
+
}
|
|
1546
|
+
const day = node.ordinalWeekday || 1;
|
|
1547
|
+
return new Date(Date.UTC(year, month2, day));
|
|
1548
|
+
}
|
|
1241
1549
|
if (node.relative && node.period) {
|
|
1242
1550
|
return convertRelativePeriod(node, opts);
|
|
1243
1551
|
}
|
|
@@ -1309,7 +1617,7 @@ function getHalfDates(half2, year, fiscalYearStart) {
|
|
|
1309
1617
|
const start = new Date(Date.UTC(startYear, halfStartMonth, 1));
|
|
1310
1618
|
const endMonth = (halfStartMonth + 6) % 12;
|
|
1311
1619
|
let endYear = startYear;
|
|
1312
|
-
if (endMonth
|
|
1620
|
+
if (endMonth <= halfStartMonth) {
|
|
1313
1621
|
endYear++;
|
|
1314
1622
|
}
|
|
1315
1623
|
const end = new Date(Date.UTC(endYear, endMonth, 0));
|
|
@@ -1382,8 +1690,115 @@ function getModifiedPeriod(start, end, modifier) {
|
|
|
1382
1690
|
}
|
|
1383
1691
|
|
|
1384
1692
|
// src/converters/fuzzy.ts
|
|
1693
|
+
function getWeekendDates(ref, relative, opts) {
|
|
1694
|
+
const currentDay = ref.getUTCDay();
|
|
1695
|
+
const saturdayOffset = (6 - currentDay + 7) % 7;
|
|
1696
|
+
let saturday = new Date(
|
|
1697
|
+
Date.UTC(
|
|
1698
|
+
ref.getUTCFullYear(),
|
|
1699
|
+
ref.getUTCMonth(),
|
|
1700
|
+
ref.getUTCDate() + saturdayOffset
|
|
1701
|
+
)
|
|
1702
|
+
);
|
|
1703
|
+
if (relative === "next") {
|
|
1704
|
+
saturday = new Date(saturday.getTime() + MS_PER_WEEK);
|
|
1705
|
+
} else if (relative === "last") {
|
|
1706
|
+
if (currentDay === 6 || currentDay === 0) {
|
|
1707
|
+
saturday = new Date(saturday.getTime() - MS_PER_WEEK);
|
|
1708
|
+
}
|
|
1709
|
+
saturday = new Date(saturday.getTime() - MS_PER_WEEK);
|
|
1710
|
+
}
|
|
1711
|
+
const sunday = new Date(saturday.getTime() + MS_PER_DAY);
|
|
1712
|
+
const sundayEnd = new Date(
|
|
1713
|
+
Date.UTC(
|
|
1714
|
+
sunday.getUTCFullYear(),
|
|
1715
|
+
sunday.getUTCMonth(),
|
|
1716
|
+
sunday.getUTCDate(),
|
|
1717
|
+
23,
|
|
1718
|
+
59
|
|
1719
|
+
)
|
|
1720
|
+
);
|
|
1721
|
+
return { start: saturday, end: sundayEnd };
|
|
1722
|
+
}
|
|
1723
|
+
function getNightDates(ref, relative, weekday2) {
|
|
1724
|
+
let baseDate = new Date(ref);
|
|
1725
|
+
if (relative === "last") {
|
|
1726
|
+
baseDate = new Date(
|
|
1727
|
+
Date.UTC(
|
|
1728
|
+
ref.getUTCFullYear(),
|
|
1729
|
+
ref.getUTCMonth(),
|
|
1730
|
+
ref.getUTCDate() - 1
|
|
1731
|
+
)
|
|
1732
|
+
);
|
|
1733
|
+
} else if (relative === "tomorrow") {
|
|
1734
|
+
baseDate = new Date(
|
|
1735
|
+
Date.UTC(
|
|
1736
|
+
ref.getUTCFullYear(),
|
|
1737
|
+
ref.getUTCMonth(),
|
|
1738
|
+
ref.getUTCDate() + 1
|
|
1739
|
+
)
|
|
1740
|
+
);
|
|
1741
|
+
} else if (weekday2) {
|
|
1742
|
+
const targetDay = WEEKDAY_MAP[weekday2.toLowerCase()];
|
|
1743
|
+
if (targetDay !== void 0) {
|
|
1744
|
+
const currentDay = ref.getUTCDay();
|
|
1745
|
+
let daysToAdd = (targetDay - currentDay + 7) % 7;
|
|
1746
|
+
if (daysToAdd === 0) {
|
|
1747
|
+
daysToAdd = 7;
|
|
1748
|
+
}
|
|
1749
|
+
baseDate = new Date(
|
|
1750
|
+
Date.UTC(
|
|
1751
|
+
ref.getUTCFullYear(),
|
|
1752
|
+
ref.getUTCMonth(),
|
|
1753
|
+
ref.getUTCDate() + daysToAdd
|
|
1754
|
+
)
|
|
1755
|
+
);
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
const start = new Date(
|
|
1759
|
+
Date.UTC(
|
|
1760
|
+
baseDate.getUTCFullYear(),
|
|
1761
|
+
baseDate.getUTCMonth(),
|
|
1762
|
+
baseDate.getUTCDate(),
|
|
1763
|
+
18,
|
|
1764
|
+
0
|
|
1765
|
+
)
|
|
1766
|
+
);
|
|
1767
|
+
const end = new Date(
|
|
1768
|
+
Date.UTC(
|
|
1769
|
+
baseDate.getUTCFullYear(),
|
|
1770
|
+
baseDate.getUTCMonth(),
|
|
1771
|
+
baseDate.getUTCDate(),
|
|
1772
|
+
23,
|
|
1773
|
+
59
|
|
1774
|
+
)
|
|
1775
|
+
);
|
|
1776
|
+
return { start, end };
|
|
1777
|
+
}
|
|
1385
1778
|
function getBasePeriodDates(node, opts, year) {
|
|
1386
1779
|
const ref = opts.referenceDate;
|
|
1780
|
+
if (node.period === "weekend") {
|
|
1781
|
+
return getWeekendDates(ref, node.relative || "this", opts);
|
|
1782
|
+
}
|
|
1783
|
+
if (node.period === "tonight") {
|
|
1784
|
+
return getNightDates(ref, void 0, void 0);
|
|
1785
|
+
}
|
|
1786
|
+
if (node.period === "night") {
|
|
1787
|
+
return getNightDates(ref, node.relative, node.weekday);
|
|
1788
|
+
}
|
|
1789
|
+
if (node.period === "fortnight") {
|
|
1790
|
+
const count = node.count || 1;
|
|
1791
|
+
const relative = node.relative;
|
|
1792
|
+
const twoWeeks = 14 * MS_PER_DAY;
|
|
1793
|
+
if (relative === "last") {
|
|
1794
|
+
const end2 = new Date(ref);
|
|
1795
|
+
const start2 = new Date(ref.getTime() - twoWeeks);
|
|
1796
|
+
return { start: start2, end: end2 };
|
|
1797
|
+
}
|
|
1798
|
+
const start = new Date(ref);
|
|
1799
|
+
const end = new Date(ref.getTime() + count * twoWeeks);
|
|
1800
|
+
return { start, end };
|
|
1801
|
+
}
|
|
1387
1802
|
if (node.period === "quarter" && node.quarter) {
|
|
1388
1803
|
return getQuarterDates(
|
|
1389
1804
|
node.quarter,
|
|
@@ -1423,6 +1838,42 @@ function getBasePeriodDates(node, opts, year) {
|
|
|
1423
1838
|
const end = new Date(start.getTime() + 6 * MS_PER_DAY);
|
|
1424
1839
|
return { start, end };
|
|
1425
1840
|
}
|
|
1841
|
+
if (node.period === "weekNumber" && node.weekNumber !== void 0) {
|
|
1842
|
+
const weekNum = node.weekNumber;
|
|
1843
|
+
const targetYear = node.year ?? ref.getUTCFullYear();
|
|
1844
|
+
const weekStart = opts.weekStartsOn === "monday" ? 1 : 0;
|
|
1845
|
+
const jan1 = new Date(Date.UTC(targetYear, 0, 1));
|
|
1846
|
+
const jan1Day = jan1.getUTCDay();
|
|
1847
|
+
const daysToFirstWeekStart = (weekStart - jan1Day + 7) % 7;
|
|
1848
|
+
const firstWeekStart = new Date(jan1.getTime() + daysToFirstWeekStart * MS_PER_DAY);
|
|
1849
|
+
const start = new Date(firstWeekStart.getTime() + (weekNum - 1) * MS_PER_WEEK);
|
|
1850
|
+
const end = new Date(start.getTime() + 6 * MS_PER_DAY);
|
|
1851
|
+
return { start, end };
|
|
1852
|
+
}
|
|
1853
|
+
if (node.period === "weekOf" && node.baseDate) {
|
|
1854
|
+
const baseDate = node.baseDate;
|
|
1855
|
+
let targetDate;
|
|
1856
|
+
if (baseDate.month !== void 0 && baseDate.day !== void 0) {
|
|
1857
|
+
const month2 = typeof baseDate.month === "number" ? baseDate.month - 1 : 0;
|
|
1858
|
+
const day = baseDate.day;
|
|
1859
|
+
const targetYear = baseDate.year ?? ref.getUTCFullYear();
|
|
1860
|
+
targetDate = new Date(Date.UTC(targetYear, month2, day));
|
|
1861
|
+
} else {
|
|
1862
|
+
targetDate = ref;
|
|
1863
|
+
}
|
|
1864
|
+
const weekStart = opts.weekStartsOn === "monday" ? 1 : 0;
|
|
1865
|
+
const currentDay = targetDate.getUTCDay();
|
|
1866
|
+
const daysFromStart = (currentDay - weekStart + 7) % 7;
|
|
1867
|
+
const start = new Date(
|
|
1868
|
+
Date.UTC(
|
|
1869
|
+
targetDate.getUTCFullYear(),
|
|
1870
|
+
targetDate.getUTCMonth(),
|
|
1871
|
+
targetDate.getUTCDate() - daysFromStart
|
|
1872
|
+
)
|
|
1873
|
+
);
|
|
1874
|
+
const end = new Date(start.getTime() + 6 * MS_PER_DAY);
|
|
1875
|
+
return { start, end };
|
|
1876
|
+
}
|
|
1426
1877
|
if (node.period === "day") {
|
|
1427
1878
|
const start = new Date(
|
|
1428
1879
|
Date.UTC(ref.getUTCFullYear(), ref.getUTCMonth(), ref.getUTCDate())
|
|
@@ -1546,7 +1997,7 @@ function convertASTToResult(ast, opts, originalInput) {
|
|
|
1546
1997
|
end = new Date(Date.UTC(year, month2 + 1, 0));
|
|
1547
1998
|
}
|
|
1548
1999
|
if (endNode.yearOnly) {
|
|
1549
|
-
const year = endNode.year;
|
|
2000
|
+
const year = endNode.year ?? opts.referenceDate.getUTCFullYear();
|
|
1550
2001
|
end = new Date(Date.UTC(year, 11, 31));
|
|
1551
2002
|
}
|
|
1552
2003
|
} else if (endNode.nodeType === "fuzzy") {
|
|
@@ -1577,6 +2028,7 @@ function convertASTToResult(ast, opts, originalInput) {
|
|
|
1577
2028
|
case "fuzzy": {
|
|
1578
2029
|
const { start, end } = convertFuzzyNode(expression, opts);
|
|
1579
2030
|
const mod = expression.modifier;
|
|
2031
|
+
const period = expression.period;
|
|
1580
2032
|
if (mod === "start" || mod === "beginning") {
|
|
1581
2033
|
const periodDates = convertFuzzyNodeWithoutModifier(expression, opts);
|
|
1582
2034
|
return { type: "date", date: periodDates.start, title };
|
|
@@ -1585,6 +2037,10 @@ function convertASTToResult(ast, opts, originalInput) {
|
|
|
1585
2037
|
const periodDates = convertFuzzyNodeWithoutModifier(expression, opts);
|
|
1586
2038
|
return { type: "date", date: periodDates.end, title };
|
|
1587
2039
|
}
|
|
2040
|
+
if (period === "weekend" || period === "night" || period === "tonight" || period === "fortnight" || period === "weekNumber" || period === "weekOf") {
|
|
2041
|
+
const duration = end.getTime() - start.getTime();
|
|
2042
|
+
return { type: "span", start, end, duration, title };
|
|
2043
|
+
}
|
|
1588
2044
|
return { type: "fuzzy", start, end, approximate: true, title };
|
|
1589
2045
|
}
|
|
1590
2046
|
case "relative": {
|
|
@@ -1601,6 +2057,91 @@ function convertASTToResult(ast, opts, originalInput) {
|
|
|
1601
2057
|
}
|
|
1602
2058
|
return { type: "span", start, end, duration, title };
|
|
1603
2059
|
}
|
|
2060
|
+
case "relativeDate": {
|
|
2061
|
+
const durationNode = expression.duration;
|
|
2062
|
+
const baseNode = expression.baseDate;
|
|
2063
|
+
const timeSpec = expression.time;
|
|
2064
|
+
let baseDate;
|
|
2065
|
+
if (baseNode) {
|
|
2066
|
+
baseDate = convertDateNode(baseNode, opts);
|
|
2067
|
+
} else {
|
|
2068
|
+
baseDate = new Date(opts.referenceDate);
|
|
2069
|
+
}
|
|
2070
|
+
const durationValue = durationNode.value;
|
|
2071
|
+
const durationUnit = durationNode.unit;
|
|
2072
|
+
const direction = expression.direction === "past" ? -1 : 1;
|
|
2073
|
+
let resultDate;
|
|
2074
|
+
if (durationUnit === "month") {
|
|
2075
|
+
resultDate = new Date(
|
|
2076
|
+
Date.UTC(
|
|
2077
|
+
baseDate.getUTCFullYear(),
|
|
2078
|
+
baseDate.getUTCMonth() + direction * durationValue,
|
|
2079
|
+
baseDate.getUTCDate(),
|
|
2080
|
+
baseDate.getUTCHours(),
|
|
2081
|
+
baseDate.getUTCMinutes()
|
|
2082
|
+
)
|
|
2083
|
+
);
|
|
2084
|
+
} else if (durationUnit === "year") {
|
|
2085
|
+
resultDate = new Date(
|
|
2086
|
+
Date.UTC(
|
|
2087
|
+
baseDate.getUTCFullYear() + direction * durationValue,
|
|
2088
|
+
baseDate.getUTCMonth(),
|
|
2089
|
+
baseDate.getUTCDate(),
|
|
2090
|
+
baseDate.getUTCHours(),
|
|
2091
|
+
baseDate.getUTCMinutes()
|
|
2092
|
+
)
|
|
2093
|
+
);
|
|
2094
|
+
} else if (durationUnit === "businessDay" || durationUnit === "businessday") {
|
|
2095
|
+
resultDate = new Date(Date.UTC(baseDate.getUTCFullYear(), baseDate.getUTCMonth(), baseDate.getUTCDate()));
|
|
2096
|
+
let daysToAdd = durationValue;
|
|
2097
|
+
while (daysToAdd > 0) {
|
|
2098
|
+
resultDate.setUTCDate(resultDate.getUTCDate() + direction);
|
|
2099
|
+
const dayOfWeek = resultDate.getUTCDay();
|
|
2100
|
+
if (dayOfWeek !== 0 && dayOfWeek !== 6) {
|
|
2101
|
+
daysToAdd--;
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
} else {
|
|
2105
|
+
const durationMs = convertDurationNode(durationNode);
|
|
2106
|
+
resultDate = new Date(baseDate.getTime() + direction * durationMs);
|
|
2107
|
+
}
|
|
2108
|
+
if (timeSpec) {
|
|
2109
|
+
if ("special" in timeSpec) {
|
|
2110
|
+
if (timeSpec.special === "noon") {
|
|
2111
|
+
resultDate = new Date(
|
|
2112
|
+
Date.UTC(
|
|
2113
|
+
resultDate.getUTCFullYear(),
|
|
2114
|
+
resultDate.getUTCMonth(),
|
|
2115
|
+
resultDate.getUTCDate(),
|
|
2116
|
+
12,
|
|
2117
|
+
0
|
|
2118
|
+
)
|
|
2119
|
+
);
|
|
2120
|
+
} else if (timeSpec.special === "midnight") {
|
|
2121
|
+
resultDate = new Date(
|
|
2122
|
+
Date.UTC(
|
|
2123
|
+
resultDate.getUTCFullYear(),
|
|
2124
|
+
resultDate.getUTCMonth(),
|
|
2125
|
+
resultDate.getUTCDate(),
|
|
2126
|
+
0,
|
|
2127
|
+
0
|
|
2128
|
+
)
|
|
2129
|
+
);
|
|
2130
|
+
}
|
|
2131
|
+
} else {
|
|
2132
|
+
resultDate = new Date(
|
|
2133
|
+
Date.UTC(
|
|
2134
|
+
resultDate.getUTCFullYear(),
|
|
2135
|
+
resultDate.getUTCMonth(),
|
|
2136
|
+
resultDate.getUTCDate(),
|
|
2137
|
+
timeSpec.hour,
|
|
2138
|
+
timeSpec.minute
|
|
2139
|
+
)
|
|
2140
|
+
);
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
return { type: "date", date: resultDate, title };
|
|
2144
|
+
}
|
|
1604
2145
|
default:
|
|
1605
2146
|
return null;
|
|
1606
2147
|
}
|
|
@@ -1623,13 +2164,13 @@ function stripUnmatchedPunctuation(input) {
|
|
|
1623
2164
|
openParens = (result.match(/\(/g) || []).length;
|
|
1624
2165
|
closeParens = (result.match(/\)/g) || []).length;
|
|
1625
2166
|
while (openParens > closeParens) {
|
|
1626
|
-
result = result.replace(
|
|
2167
|
+
result = result.replace(/\(/, "");
|
|
1627
2168
|
openParens--;
|
|
1628
2169
|
}
|
|
1629
2170
|
openBrackets = (result.match(/\[/g) || []).length;
|
|
1630
2171
|
closeBrackets = (result.match(/]/g) || []).length;
|
|
1631
2172
|
while (openBrackets > closeBrackets) {
|
|
1632
|
-
result = result.replace(
|
|
2173
|
+
result = result.replace(/\[/, "");
|
|
1633
2174
|
openBrackets--;
|
|
1634
2175
|
}
|
|
1635
2176
|
return {
|