cronli5 0.2.0 → 0.2.1
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/CHANGELOG.md +25 -0
- package/README.md +4 -4
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +123 -104
- package/dist/cronli5.js +123 -104
- package/dist/lang/de.cjs +65 -65
- package/dist/lang/de.js +65 -65
- package/dist/lang/en.cjs +122 -101
- package/dist/lang/en.js +122 -101
- package/dist/lang/es.cjs +71 -72
- package/dist/lang/es.js +71 -72
- package/dist/lang/fi.cjs +71 -66
- package/dist/lang/fi.js +71 -66
- package/dist/lang/zh.cjs +36 -36
- package/dist/lang/zh.js +36 -36
- package/package.json +1 -1
- package/src/core/analyze.ts +14 -13
- package/src/core/ir.ts +8 -8
- package/src/core/shapes.ts +8 -1
- package/src/core/util.ts +86 -3
- package/src/core/validate.ts +1 -1
- package/src/cronli5.ts +3 -3
- package/src/lang/de/index.ts +30 -99
- package/src/lang/en/index.ts +163 -188
- package/src/lang/es/index.ts +36 -120
- package/src/lang/fi/index.ts +33 -104
- package/src/lang/zh/index.ts +23 -48
- package/src/types.ts +2 -2
- package/types/core/analyze.d.ts +2 -2
- package/types/core/ir.d.ts +7 -7
- package/types/core/shapes.d.ts +2 -1
- package/types/core/util.d.ts +17 -2
- package/types/types.d.ts +1 -1
package/dist/lang/fi.js
CHANGED
|
@@ -69,6 +69,48 @@ function orderWeekdaysForDisplay(segments) {
|
|
|
69
69
|
function toFieldNumber(token, numberMap) {
|
|
70
70
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
71
71
|
}
|
|
72
|
+
function segmentsOf(ir, field) {
|
|
73
|
+
return ir.analyses.segments[field] ?? [];
|
|
74
|
+
}
|
|
75
|
+
function stepSegment(ir, field) {
|
|
76
|
+
return segmentsOf(ir, field)[0];
|
|
77
|
+
}
|
|
78
|
+
function singleValues(segments) {
|
|
79
|
+
const values = [];
|
|
80
|
+
for (const segment of segments) {
|
|
81
|
+
if (segment.kind !== "single") {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
values.push(+segment.value);
|
|
85
|
+
}
|
|
86
|
+
return values;
|
|
87
|
+
}
|
|
88
|
+
function offsetCleanStride(stride) {
|
|
89
|
+
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
90
|
+
}
|
|
91
|
+
function hourListStride(values) {
|
|
92
|
+
if (values.length < 2) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const interval = values[1] - values[0];
|
|
96
|
+
if (interval < 2) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
100
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (values[0] !== 0 && values.length < 5) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
return { interval, last: values[values.length - 1], start: values[0] };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/core/shapes.ts
|
|
111
|
+
function isOpenStep(field) {
|
|
112
|
+
return field.indexOf("/") !== -1 && field.indexOf("-") === -1 && field.indexOf(",") === -1;
|
|
113
|
+
}
|
|
72
114
|
|
|
73
115
|
// src/lang/fi/dialects.ts
|
|
74
116
|
var dialects = {
|
|
@@ -87,9 +129,6 @@ function resolveDialect(dialect) {
|
|
|
87
129
|
}
|
|
88
130
|
|
|
89
131
|
// src/lang/fi/index.ts
|
|
90
|
-
function stepSegment(segments) {
|
|
91
|
-
return segments[0];
|
|
92
|
-
}
|
|
93
132
|
var genitives = [
|
|
94
133
|
null,
|
|
95
134
|
"yhden",
|
|
@@ -265,7 +304,7 @@ function renderSecondsWithinMinute(ir, plan, opts) {
|
|
|
265
304
|
return secondsLeadClause(ir, opts) + ", " + atMarks(minuteField, units.minute, true) + trailingQualifier(ir, opts);
|
|
266
305
|
}
|
|
267
306
|
function composeSecondsOverMinuteStep(ir, freq, opts) {
|
|
268
|
-
const seg = stepSegment(ir
|
|
307
|
+
const seg = stepSegment(ir, "minute");
|
|
269
308
|
const stepPhrase = stepCycle60(seg, units.minute, opts);
|
|
270
309
|
if (freq.hours.kind === "during" && minuteStepIsAnchored(seg)) {
|
|
271
310
|
const bareHours = kloFromTimes(ir, freq.hours.times, opts);
|
|
@@ -277,7 +316,7 @@ function composeSecondsOverMinuteStep(ir, freq, opts) {
|
|
|
277
316
|
} else if (freq.hours.kind === "window") {
|
|
278
317
|
hourClause = " " + hourWindow(freq.hours, opts);
|
|
279
318
|
} else if (freq.hours.kind === "step") {
|
|
280
|
-
hourClause = " " + everyNthHour(stepSegment(ir
|
|
319
|
+
hourClause = " " + everyNthHour(stepSegment(ir, "hour"), opts);
|
|
281
320
|
}
|
|
282
321
|
return stepPhrase + ", " + secondsLeadClause(ir, opts) + hourClause + trailingQualifier(ir, opts);
|
|
283
322
|
}
|
|
@@ -311,7 +350,7 @@ function isEveryOtherMinuteSeconds(ir, plan) {
|
|
|
311
350
|
if (plan.rest.kind !== "minuteFrequency" || ir.pattern.second !== "*" || ir.shapes.hour !== "wildcard") {
|
|
312
351
|
return false;
|
|
313
352
|
}
|
|
314
|
-
const seg = stepSegment(ir
|
|
353
|
+
const seg = stepSegment(ir, "minute");
|
|
315
354
|
return seg.startToken === "*" && seg.interval === 2;
|
|
316
355
|
}
|
|
317
356
|
function composeMinuteZero(ir, rest, opts) {
|
|
@@ -333,7 +372,7 @@ function secondsLeadClause(ir, opts) {
|
|
|
333
372
|
}
|
|
334
373
|
if (shape === "step") {
|
|
335
374
|
return stepCycle60(
|
|
336
|
-
stepSegment(ir
|
|
375
|
+
stepSegment(ir, "second"),
|
|
337
376
|
units.second,
|
|
338
377
|
opts
|
|
339
378
|
);
|
|
@@ -342,8 +381,8 @@ function secondsLeadClause(ir, opts) {
|
|
|
342
381
|
if (shape === "single") {
|
|
343
382
|
return atMarks(secondField, units.second, marked);
|
|
344
383
|
}
|
|
345
|
-
return strideFromSegments(ir
|
|
346
|
-
joinList(segmentWords(ir
|
|
384
|
+
return strideFromSegments(segmentsOf(ir, "second"), units.second, opts) ?? atMarks(
|
|
385
|
+
joinList(segmentWords(segmentsOf(ir, "second"))),
|
|
347
386
|
units.second,
|
|
348
387
|
marked
|
|
349
388
|
);
|
|
@@ -361,15 +400,15 @@ function renderMultipleMinutes(ir, plan, opts) {
|
|
|
361
400
|
return minutesList(ir, opts) + trailingQualifier(ir, opts);
|
|
362
401
|
}
|
|
363
402
|
function minutesList(ir, opts) {
|
|
364
|
-
return strideFromSegments(ir
|
|
365
|
-
joinList(segmentWords(ir
|
|
403
|
+
return strideFromSegments(segmentsOf(ir, "minute"), units.minute, opts) ?? atMarks(
|
|
404
|
+
joinList(segmentWords(segmentsOf(ir, "minute"))),
|
|
366
405
|
units.minute,
|
|
367
406
|
true
|
|
368
407
|
);
|
|
369
408
|
}
|
|
370
409
|
function bareMinutes(ir, opts) {
|
|
371
|
-
return strideFromSegments(ir
|
|
372
|
-
joinList(segmentWords(ir
|
|
410
|
+
return strideFromSegments(segmentsOf(ir, "minute"), units.minute, opts) ?? atMarks(
|
|
411
|
+
joinList(segmentWords(segmentsOf(ir, "minute"))),
|
|
373
412
|
units.minute,
|
|
374
413
|
false
|
|
375
414
|
);
|
|
@@ -400,15 +439,15 @@ function hoursAreRangeIsolated(segments) {
|
|
|
400
439
|
return hasRange && hasSingle;
|
|
401
440
|
}
|
|
402
441
|
function hoursFirstMinutes(hoursStr, ir, opts) {
|
|
403
|
-
const stride = strideFromSegments(ir
|
|
442
|
+
const stride = strideFromSegments(segmentsOf(ir, "minute"), units.minute, opts);
|
|
404
443
|
if (stride) {
|
|
405
444
|
return hoursStr + " aina " + stride;
|
|
406
445
|
}
|
|
407
|
-
return hoursStr + " aina minuuttien " + joinList(segmentWords(ir
|
|
446
|
+
return hoursStr + " aina minuuttien " + joinList(segmentWords(segmentsOf(ir, "minute"))) + " kohdalla";
|
|
408
447
|
}
|
|
409
448
|
function hourSegmentTimesWithSeka(ir, minute, second, opts) {
|
|
410
449
|
const pieces = [];
|
|
411
|
-
ir
|
|
450
|
+
segmentsOf(ir, "hour").forEach(function clock(segment) {
|
|
412
451
|
if (segment.kind === "range") {
|
|
413
452
|
pieces.push(rangeDigits(
|
|
414
453
|
{ hour: +segment.bounds[0], minute, second },
|
|
@@ -422,7 +461,7 @@ function hourSegmentTimesWithSeka(ir, minute, second, opts) {
|
|
|
422
461
|
return "klo " + pieces.slice(0, -1).join(", ") + " sek\xE4 klo " + pieces[pieces.length - 1];
|
|
423
462
|
}
|
|
424
463
|
function renderMinuteFrequency(ir, plan, opts) {
|
|
425
|
-
const seg = stepSegment(ir
|
|
464
|
+
const seg = stepSegment(ir, "minute");
|
|
426
465
|
if (plan.hours.kind === "during") {
|
|
427
466
|
const cadence = unevenHourCadence(ir, opts);
|
|
428
467
|
if (cadence !== null) {
|
|
@@ -438,7 +477,7 @@ function renderMinuteFrequency(ir, plan, opts) {
|
|
|
438
477
|
if (plan.hours.kind === "window") {
|
|
439
478
|
phrase += " " + hourWindow(plan.hours, opts);
|
|
440
479
|
} else if (plan.hours.kind === "step") {
|
|
441
|
-
phrase += " " + everyNthHour(stepSegment(ir
|
|
480
|
+
phrase += " " + everyNthHour(stepSegment(ir, "hour"), opts);
|
|
442
481
|
}
|
|
443
482
|
return phrase + trailingQualifier(ir, opts);
|
|
444
483
|
}
|
|
@@ -460,14 +499,14 @@ function renderMinutesAcrossHours(ir, plan, opts) {
|
|
|
460
499
|
if (cadence !== null) {
|
|
461
500
|
return bareMinutes(ir, opts) + ", " + cadence + trailingQualifier(ir, opts);
|
|
462
501
|
}
|
|
463
|
-
if (hoursAreRangeIsolated(ir
|
|
502
|
+
if (hoursAreRangeIsolated(segmentsOf(ir, "hour"))) {
|
|
464
503
|
return bareMinutes(ir, opts) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
465
504
|
}
|
|
466
505
|
const hoursStr = kloFromTimes(ir, plan.times, opts);
|
|
467
506
|
return hoursFirstMinutes(hoursStr, ir, opts) + trailingQualifier(ir, opts);
|
|
468
507
|
}
|
|
469
508
|
function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
470
|
-
const segment = stepSegment(ir
|
|
509
|
+
const segment = stepSegment(ir, "hour");
|
|
471
510
|
const cadence = unevenHourCadence(ir, opts);
|
|
472
511
|
if (plan.form === "wildcard") {
|
|
473
512
|
return "joka minuutti " + everyNthHour(segment, opts) + trailingQualifier(ir, opts);
|
|
@@ -552,7 +591,7 @@ function renderHourStep(ir, plan, opts) {
|
|
|
552
591
|
if (cadence !== null) {
|
|
553
592
|
return cadence + trailingQualifier(ir, opts);
|
|
554
593
|
}
|
|
555
|
-
return stepHours(stepSegment(ir
|
|
594
|
+
return stepHours(stepSegment(ir, "hour"), opts) + trailingQualifier(ir, opts);
|
|
556
595
|
}
|
|
557
596
|
function boundedWindow(plan) {
|
|
558
597
|
return { from: plan.from, last: plan.boundMinute ?? 0, to: plan.to };
|
|
@@ -588,7 +627,7 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
588
627
|
return cadence2;
|
|
589
628
|
}
|
|
590
629
|
}
|
|
591
|
-
const hourSegs = ir
|
|
630
|
+
const hourSegs = segmentsOf(ir, "hour");
|
|
592
631
|
if (hoursAreRangeIsolated(hourSegs)) {
|
|
593
632
|
if (plan.fold) {
|
|
594
633
|
return leadingQualifier(ir, opts) + hourSegmentTimesWithSeka(
|
|
@@ -649,16 +688,6 @@ function strideFromSegments(segments, unit, opts) {
|
|
|
649
688
|
const step = values && arithmeticStep(values);
|
|
650
689
|
return step ? renderStride({ ...step, cycle: 60, unit }, opts) : null;
|
|
651
690
|
}
|
|
652
|
-
function singleValues(segments) {
|
|
653
|
-
const values = [];
|
|
654
|
-
for (const segment of segments) {
|
|
655
|
-
if (segment.kind !== "single") {
|
|
656
|
-
return null;
|
|
657
|
-
}
|
|
658
|
-
values.push(+segment.value);
|
|
659
|
-
}
|
|
660
|
-
return values;
|
|
661
|
-
}
|
|
662
691
|
function stepCycle60(segment, unit, opts) {
|
|
663
692
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
664
693
|
return atMarks(joinList(wordList(segment.fires)), unit, true);
|
|
@@ -702,27 +731,6 @@ function hourStrideCadence(stride, opts) {
|
|
|
702
731
|
}
|
|
703
732
|
return cadence + " " + kloRange({ hour: start, minute: 0 }, { hour: last, minute: 0 }, opts);
|
|
704
733
|
}
|
|
705
|
-
function hourListStride(values) {
|
|
706
|
-
if (values.length < 2) {
|
|
707
|
-
return null;
|
|
708
|
-
}
|
|
709
|
-
const interval = values[1] - values[0];
|
|
710
|
-
if (interval < 2) {
|
|
711
|
-
return null;
|
|
712
|
-
}
|
|
713
|
-
for (let i = 2; i < values.length; i += 1) {
|
|
714
|
-
if (values[i] - values[i - 1] !== interval) {
|
|
715
|
-
return null;
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
if (values[0] !== 0 && values.length < 5) {
|
|
719
|
-
return null;
|
|
720
|
-
}
|
|
721
|
-
return { interval, last: values[values.length - 1], start: values[0] };
|
|
722
|
-
}
|
|
723
|
-
function offsetCleanStride(stride) {
|
|
724
|
-
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
725
|
-
}
|
|
726
734
|
function hourStride(ir) {
|
|
727
735
|
const segments = ir.analyses.segments.hour;
|
|
728
736
|
if (!segments) {
|
|
@@ -771,8 +779,8 @@ function hourCadence(ir, minute, opts) {
|
|
|
771
779
|
if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
|
|
772
780
|
return null;
|
|
773
781
|
}
|
|
774
|
-
const segment = ir
|
|
775
|
-
const confined = minute === 0 && subMinuteSecond(ir) && ir
|
|
782
|
+
const segment = segmentsOf(ir, "hour")[0];
|
|
783
|
+
const confined = minute === 0 && subMinuteSecond(ir) && segmentsOf(ir, "hour").length === 1 && segment.kind === "step" && cleanHourStride(segment);
|
|
776
784
|
if (confined) {
|
|
777
785
|
return secondsLeadClause(ir, opts) + " minuutin ajan " + everyNthHour(segment, opts) + trailingQualifier(ir, opts);
|
|
778
786
|
}
|
|
@@ -795,7 +803,7 @@ function hasHourWindow(ir) {
|
|
|
795
803
|
});
|
|
796
804
|
}
|
|
797
805
|
function hourRangeWindowTail(ir, opts) {
|
|
798
|
-
return ir
|
|
806
|
+
return segmentsOf(ir, "hour").length === 1 ? hourSegmentTimes(ir, 0, null, opts) : hourSegmentTimesWithSeka(ir, 0, null, opts);
|
|
799
807
|
}
|
|
800
808
|
function hourRangeCadence(ir, minute, opts) {
|
|
801
809
|
if (minute !== 0 || !hasHourWindow(ir) || ir.pattern.second === "0") {
|
|
@@ -823,7 +831,7 @@ function hourWindowsFromTimes(ir, times, opts) {
|
|
|
823
831
|
if (times.kind === "fires") {
|
|
824
832
|
return kloList(times.fires, opts);
|
|
825
833
|
}
|
|
826
|
-
const segments = ir
|
|
834
|
+
const segments = segmentsOf(ir, "hour");
|
|
827
835
|
if (!segments.some(function ranged(segment) {
|
|
828
836
|
return segment.kind === "range";
|
|
829
837
|
})) {
|
|
@@ -863,7 +871,7 @@ function hourWindowDigits(hour, opts) {
|
|
|
863
871
|
}
|
|
864
872
|
function hourSegmentTimes(ir, minute, second, opts) {
|
|
865
873
|
const pieces = [];
|
|
866
|
-
ir
|
|
874
|
+
segmentsOf(ir, "hour").forEach(function clock(segment) {
|
|
867
875
|
if (segment.kind === "step") {
|
|
868
876
|
pieces.push(...segment.fires.map(function each(hour) {
|
|
869
877
|
return timeDigits(hour, minute, second, opts);
|
|
@@ -959,7 +967,7 @@ function weekdayQualifier(ir) {
|
|
|
959
967
|
if (quartz) {
|
|
960
968
|
return quartz;
|
|
961
969
|
}
|
|
962
|
-
const segments = orderWeekdaysForDisplay(ir
|
|
970
|
+
const segments = orderWeekdaysForDisplay(segmentsOf(ir, "weekday"));
|
|
963
971
|
return joinList(segments.map(function piece(segment) {
|
|
964
972
|
if (segment.kind === "range") {
|
|
965
973
|
return weekdays[weekdayNumber(segment.bounds[0])].ela + " " + weekdays[weekdayNumber(segment.bounds[1])].ill;
|
|
@@ -968,7 +976,7 @@ function weekdayQualifier(ir) {
|
|
|
968
976
|
}));
|
|
969
977
|
}
|
|
970
978
|
function monthPhrase(ir) {
|
|
971
|
-
const segments = flattenSteps(ir
|
|
979
|
+
const segments = flattenSteps(segmentsOf(ir, "month"));
|
|
972
980
|
return joinList(segments.map(function piece(segment) {
|
|
973
981
|
if (segment.kind === "range") {
|
|
974
982
|
return monthStems[monthNumber(segment.bounds[0])] + "kuusta " + monthStems[monthNumber(segment.bounds[1])] + "kuuhun";
|
|
@@ -1018,7 +1026,7 @@ function monthAnchor(ir, opts) {
|
|
|
1018
1026
|
if (isOpenStep(monthField)) {
|
|
1019
1027
|
return stepMonths(monthField, opts);
|
|
1020
1028
|
}
|
|
1021
|
-
const segments = flattenSteps(ir
|
|
1029
|
+
const segments = flattenSteps(segmentsOf(ir, "month"));
|
|
1022
1030
|
return joinList(segments.map(function genitiveOf(segment) {
|
|
1023
1031
|
const single = segment;
|
|
1024
1032
|
return monthStems[monthNumber(single.value)] + "kuun";
|
|
@@ -1028,12 +1036,12 @@ function rangedMonthScope(ir) {
|
|
|
1028
1036
|
return monthRanged(ir) ? " " + monthPhrase(ir) : "";
|
|
1029
1037
|
}
|
|
1030
1038
|
function monthRanged(ir) {
|
|
1031
|
-
return ir.pattern.month !== "*" && ir
|
|
1039
|
+
return ir.pattern.month !== "*" && segmentsOf(ir, "month").some(function range(segment) {
|
|
1032
1040
|
return segment.kind === "range";
|
|
1033
1041
|
});
|
|
1034
1042
|
}
|
|
1035
1043
|
function dateWords(ir) {
|
|
1036
|
-
return joinList(ir
|
|
1044
|
+
return joinList(segmentsOf(ir, "date").flatMap(
|
|
1037
1045
|
function word(segment) {
|
|
1038
1046
|
if (segment.kind === "range") {
|
|
1039
1047
|
return [segment.bounds[0] + ".\u2013" + segment.bounds[1] + "."];
|
|
@@ -1135,9 +1143,6 @@ function segmentWords(segments) {
|
|
|
1135
1143
|
return [segment.value];
|
|
1136
1144
|
});
|
|
1137
1145
|
}
|
|
1138
|
-
function isOpenStep(field) {
|
|
1139
|
-
return field.indexOf("/") !== -1 && field.indexOf("-") === -1 && field.indexOf(",") === -1;
|
|
1140
|
-
}
|
|
1141
1146
|
function wordList(fires) {
|
|
1142
1147
|
return fires.map(function digit(value) {
|
|
1143
1148
|
return "" + value;
|
package/dist/lang/zh.cjs
CHANGED
|
@@ -67,6 +67,22 @@ function orderWeekdaysForDisplay(segments) {
|
|
|
67
67
|
function toFieldNumber(token, numberMap) {
|
|
68
68
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
69
69
|
}
|
|
70
|
+
function segmentsOf(ir, field) {
|
|
71
|
+
return ir.analyses.segments[field] ?? [];
|
|
72
|
+
}
|
|
73
|
+
function stepSegment(ir, field) {
|
|
74
|
+
return segmentsOf(ir, field)[0];
|
|
75
|
+
}
|
|
76
|
+
function singleValues(segments) {
|
|
77
|
+
const values = [];
|
|
78
|
+
for (const segment of segments) {
|
|
79
|
+
if (segment.kind !== "single") {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
values.push(+segment.value);
|
|
83
|
+
}
|
|
84
|
+
return values;
|
|
85
|
+
}
|
|
70
86
|
|
|
71
87
|
// src/core/specs.ts
|
|
72
88
|
var weekdayNumbers = {
|
|
@@ -114,12 +130,6 @@ function joinAnd(items) {
|
|
|
114
130
|
}
|
|
115
131
|
return items.slice(0, -1).join("\u3001") + "\u548C" + items[items.length - 1];
|
|
116
132
|
}
|
|
117
|
-
function fieldSegments(ir, field) {
|
|
118
|
-
return ir.analyses.segments[field] || [];
|
|
119
|
-
}
|
|
120
|
-
function stepSegment(ir, field) {
|
|
121
|
-
return fieldSegments(ir, field)[0];
|
|
122
|
-
}
|
|
123
133
|
function cadence(interval, unit) {
|
|
124
134
|
return interval === 1 ? "\u6BCF" + unit : "\u6BCF" + interval + unit;
|
|
125
135
|
}
|
|
@@ -132,16 +142,6 @@ function renderStride(stride) {
|
|
|
132
142
|
const lead = anchor + "\u4ECE" + start + mark + "\u8D77" + cadence(interval, unit);
|
|
133
143
|
return start < interval && tiles ? lead : lead + "\uFF0C\u81F3" + last + mark;
|
|
134
144
|
}
|
|
135
|
-
function singleValues(segments) {
|
|
136
|
-
const values = [];
|
|
137
|
-
for (const segment of segments) {
|
|
138
|
-
if (segment.kind !== "single") {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
values.push(+segment.value);
|
|
142
|
-
}
|
|
143
|
-
return values;
|
|
144
|
-
}
|
|
145
145
|
function strideFromSegments(segments, unit, mark, anchor) {
|
|
146
146
|
const values = singleValues(segments);
|
|
147
147
|
const step = values && arithmeticStep(values);
|
|
@@ -205,7 +205,7 @@ function hourWord(hour) {
|
|
|
205
205
|
}
|
|
206
206
|
function hourFires(ir) {
|
|
207
207
|
const fires = [];
|
|
208
|
-
|
|
208
|
+
segmentsOf(ir, "hour").forEach(function expand(segment) {
|
|
209
209
|
if (segment.kind === "step") {
|
|
210
210
|
fires.push(...segment.fires);
|
|
211
211
|
} else if (segment.kind === "range") {
|
|
@@ -260,7 +260,7 @@ function renderEveryHour() {
|
|
|
260
260
|
return "\u6BCF\u5C0F\u65F6";
|
|
261
261
|
}
|
|
262
262
|
function minuteHourClause(ir) {
|
|
263
|
-
const segments =
|
|
263
|
+
const segments = segmentsOf(ir, "minute");
|
|
264
264
|
if (ir.shapes.minute === "step") {
|
|
265
265
|
return stepClause(stepSegment(ir, "minute"), "\u5206\u949F", "\u5206", "\u6BCF\u5C0F\u65F6");
|
|
266
266
|
}
|
|
@@ -279,12 +279,12 @@ function hourSegmentWords(segment) {
|
|
|
279
279
|
return [hourWord(+segment.value)];
|
|
280
280
|
}
|
|
281
281
|
function hourList(ir) {
|
|
282
|
-
const words =
|
|
282
|
+
const words = segmentsOf(ir, "hour").flatMap(hourSegmentWords);
|
|
283
283
|
return joinAnd(words);
|
|
284
284
|
}
|
|
285
285
|
function hourFrame(ir) {
|
|
286
286
|
if (ir.shapes.hour === "range") {
|
|
287
|
-
const [from, to] =
|
|
287
|
+
const [from, to] = segmentsOf(ir, "hour")[0].bounds;
|
|
288
288
|
return "\u5728" + hourWord(+from) + "\u81F3" + hourWord(+to) + "\u4E4B\u95F4\uFF0C";
|
|
289
289
|
}
|
|
290
290
|
return "\u5728" + hourList(ir) + "\uFF0C";
|
|
@@ -355,7 +355,7 @@ function renderCompactClockTimes(ir, plan) {
|
|
|
355
355
|
return cad;
|
|
356
356
|
}
|
|
357
357
|
const compact = plan;
|
|
358
|
-
const secs =
|
|
358
|
+
const secs = segmentsOf(ir, "second");
|
|
359
359
|
const tail = secs.length && ir.pattern.second !== "0" ? "\uFF0C\u7B2C" + valueText(secs) + "\u79D2" : "";
|
|
360
360
|
if (!compact.fold) {
|
|
361
361
|
const hourCad = hourCadencePhrase(ir);
|
|
@@ -369,12 +369,12 @@ function renderCompactClockTimes(ir, plan) {
|
|
|
369
369
|
function renderHourRange(ir, plan) {
|
|
370
370
|
const range = plan;
|
|
371
371
|
if (range.minuteForm === "lead") {
|
|
372
|
-
const minuteSegs =
|
|
372
|
+
const minuteSegs = segmentsOf(ir, "minute");
|
|
373
373
|
const past = minuteSegs.length && ir.pattern.minute !== "0" ? minuteHourClause(ir) : "\u6BCF\u5C0F\u65F6";
|
|
374
374
|
return "\u5728" + hourWord(range.from) + "\u81F3" + hourWord(range.to) + "\u4E4B\u95F4\uFF0C" + past;
|
|
375
375
|
}
|
|
376
376
|
if (range.minuteForm === "range") {
|
|
377
|
-
return "\u5728" + hourWord(range.from) + "\u81F3" + hourWord(range.to) + "\u4E4B\u95F4\uFF0C\u6BCF\u5C0F\u65F6" + valueList(
|
|
377
|
+
return "\u5728" + hourWord(range.from) + "\u81F3" + hourWord(range.to) + "\u4E4B\u95F4\uFF0C\u6BCF\u5C0F\u65F6" + valueList(segmentsOf(ir, "minute"), "\u5206") + "\uFF0C\u6BCF\u5206\u949F";
|
|
378
378
|
}
|
|
379
379
|
return "\u5728" + hourWord(range.from) + "\u81F3" + range.to + "\u70B9" + range.last + "\u5206\u4E4B\u95F4\uFF0C\u6BCF\u5206\u949F";
|
|
380
380
|
}
|
|
@@ -386,7 +386,7 @@ function renderHourStep(ir) {
|
|
|
386
386
|
return hourCadencePhrase(ir);
|
|
387
387
|
}
|
|
388
388
|
function hourStride(ir) {
|
|
389
|
-
const segments =
|
|
389
|
+
const segments = segmentsOf(ir, "hour");
|
|
390
390
|
if (segments.length === 1 && segments[0].kind === "step") {
|
|
391
391
|
const { fires, interval } = segments[0];
|
|
392
392
|
return { interval, start: fires[0], last: fires[fires.length - 1] };
|
|
@@ -453,7 +453,7 @@ function renderRangeOfMinutes(ir) {
|
|
|
453
453
|
return minuteHourClause(ir) + "\uFF0C\u6BCF\u5206\u949F";
|
|
454
454
|
}
|
|
455
455
|
function renderStandaloneSeconds(ir) {
|
|
456
|
-
const segs =
|
|
456
|
+
const segs = segmentsOf(ir, "second");
|
|
457
457
|
const first = segs[0];
|
|
458
458
|
if (segs.length === 1 && first.kind === "step" && first.startToken === "*") {
|
|
459
459
|
return cadence(first.interval, UNITS.second);
|
|
@@ -461,11 +461,11 @@ function renderStandaloneSeconds(ir) {
|
|
|
461
461
|
return strideFromSegments(segs, "\u79D2", "\u79D2", "\u6BCF\u5206\u949F") ?? "\u6BCF\u5206\u949F\u7B2C" + valueText(segs) + "\u79D2";
|
|
462
462
|
}
|
|
463
463
|
function renderSecondPastMinute(ir) {
|
|
464
|
-
return "\u6BCF\u5206\u949F\u7B2C" + valueText(
|
|
464
|
+
return "\u6BCF\u5206\u949F\u7B2C" + valueText(segmentsOf(ir, "second")) + "\u79D2";
|
|
465
465
|
}
|
|
466
466
|
function renderSecondsWithinMinute(ir) {
|
|
467
467
|
const base = "\u6BCF\u5C0F\u65F6" + ir.pattern.minute + "\u5206";
|
|
468
|
-
const segs =
|
|
468
|
+
const segs = segmentsOf(ir, "second");
|
|
469
469
|
const first = segs[0];
|
|
470
470
|
if (segs.length === 1 && first.kind === "step" && first.startToken === "*") {
|
|
471
471
|
return base + "\uFF0C" + cadence(first.interval, UNITS.second);
|
|
@@ -473,7 +473,7 @@ function renderSecondsWithinMinute(ir) {
|
|
|
473
473
|
return base + "\u7B2C" + valueText(segs) + "\u79D2";
|
|
474
474
|
}
|
|
475
475
|
function secondClause(ir) {
|
|
476
|
-
const segs =
|
|
476
|
+
const segs = segmentsOf(ir, "second");
|
|
477
477
|
if (!segs.length) {
|
|
478
478
|
return "\u6BCF\u79D2";
|
|
479
479
|
}
|
|
@@ -490,7 +490,7 @@ function minuteClause(ir) {
|
|
|
490
490
|
if (ir.shapes.minute === "step") {
|
|
491
491
|
return cadence(stepSegment(ir, "minute").interval, UNITS.minute);
|
|
492
492
|
}
|
|
493
|
-
return valueList(
|
|
493
|
+
return valueList(segmentsOf(ir, "minute"), "\u5206");
|
|
494
494
|
}
|
|
495
495
|
function clockRestCarriesSecond(rest) {
|
|
496
496
|
return rest.kind === "clockTimes" && rest.times.some((time) => Boolean(time.second));
|
|
@@ -525,13 +525,13 @@ function composeMinuteZeroClocks(ir, sec) {
|
|
|
525
525
|
const clocks = hourFires(ir).map(function clock(hour) {
|
|
526
526
|
return hour === 12 ? "\u6B63\u5348" : hourWord(hour) + "0\u5206";
|
|
527
527
|
});
|
|
528
|
-
const nested = strideFromSegments(
|
|
528
|
+
const nested = strideFromSegments(segmentsOf(ir, "second"), "\u79D2", "\u79D2", "");
|
|
529
529
|
const tail = sec === "\u6BCF\u79D2" ? "\u7684\u6BCF\u4E00\u79D2" : "\u7684" + (nested ?? sec);
|
|
530
530
|
const core = joinAnd(clocks) + tail;
|
|
531
531
|
return isDaily(ir) ? "\u6BCF\u5929" + core : core;
|
|
532
532
|
}
|
|
533
533
|
function hasHourWindow(ir) {
|
|
534
|
-
return
|
|
534
|
+
return segmentsOf(ir, "hour").some(function range(segment) {
|
|
535
535
|
return segment.kind === "range";
|
|
536
536
|
});
|
|
537
537
|
}
|
|
@@ -567,7 +567,7 @@ function composeSecondsListed(ir) {
|
|
|
567
567
|
const sec = secondClause(ir);
|
|
568
568
|
const minutes = minuteHourClause(ir);
|
|
569
569
|
if (ir.shapes.hour === "single" && sec === "\u6BCF\u79D2") {
|
|
570
|
-
const minuteSegs =
|
|
570
|
+
const minuteSegs = segmentsOf(ir, "minute");
|
|
571
571
|
const minuteCad = strideFromSegments(minuteSegs, "\u5206\u949F", "\u5206", "") ?? valueList(minuteSegs, "\u5206");
|
|
572
572
|
return hourWord(hourFires(ir)[0]) + minuteCad + "\u7684\u6BCF\u4E00\u79D2";
|
|
573
573
|
}
|
|
@@ -623,7 +623,7 @@ function monthPhrase(ir) {
|
|
|
623
623
|
if (ir.pattern.month === "*") {
|
|
624
624
|
return "";
|
|
625
625
|
}
|
|
626
|
-
const segs =
|
|
626
|
+
const segs = segmentsOf(ir, "month");
|
|
627
627
|
const first = segs[0];
|
|
628
628
|
if (segs.length === 1 && first.kind === "step" && first.interval === 2) {
|
|
629
629
|
return "\u6BCF\u4E2A" + (first.fires[0] % 2 ? "\u5947" : "\u5076") + "\u6570\u6708";
|
|
@@ -642,7 +642,7 @@ function monthPhrase(ir) {
|
|
|
642
642
|
return nums.join("\u3001") + "\u6708";
|
|
643
643
|
}
|
|
644
644
|
function dayList(ir) {
|
|
645
|
-
const segs =
|
|
645
|
+
const segs = segmentsOf(ir, "date");
|
|
646
646
|
if (segs.every((seg) => seg.kind === "single")) {
|
|
647
647
|
return segs.map((seg) => seg.value).join("\u3001") + "\u65E5";
|
|
648
648
|
}
|
|
@@ -717,7 +717,7 @@ function weekdayPhrase(ir, orContext, monthPrefix) {
|
|
|
717
717
|
if (ir.shapes.weekday === "quartz") {
|
|
718
718
|
return quartzWeekday(ir.pattern.weekday, monthPrefix);
|
|
719
719
|
}
|
|
720
|
-
const segs =
|
|
720
|
+
const segs = segmentsOf(ir, "weekday");
|
|
721
721
|
if (segs.length === 1 && segs[0].kind === "range") {
|
|
722
722
|
const [from, to] = segs[0].bounds;
|
|
723
723
|
return "\u6BCF" + weekdayName(from) + "\u81F3" + weekdayName(to);
|
|
@@ -811,7 +811,7 @@ function describe(ir, opts) {
|
|
|
811
811
|
if (ir.pattern.year === "*") {
|
|
812
812
|
return composed;
|
|
813
813
|
}
|
|
814
|
-
const year =
|
|
814
|
+
const year = segmentsOf(ir, "year").map(function part(seg) {
|
|
815
815
|
if (seg.kind === "range") {
|
|
816
816
|
return seg.bounds[0] + "\u5E74\u81F3" + seg.bounds[1] + "\u5E74";
|
|
817
817
|
}
|