cronli5 0.1.6 → 0.2.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/CHANGELOG.md +86 -0
- package/README.md +6 -6
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +401 -81
- package/dist/cronli5.js +401 -81
- package/dist/lang/de.cjs +63 -17
- package/dist/lang/de.js +63 -17
- package/dist/lang/en.cjs +401 -81
- package/dist/lang/en.js +401 -81
- package/dist/lang/es.cjs +68 -5
- package/dist/lang/es.js +68 -5
- package/dist/lang/fi.cjs +21 -1
- package/dist/lang/fi.js +21 -1
- package/dist/lang/zh.cjs +38 -7
- package/dist/lang/zh.js +38 -7
- package/package.json +1 -1
- package/src/core/ir.ts +5 -0
- package/src/core/util.ts +52 -1
- package/src/lang/de/index.ts +95 -25
- package/src/lang/en/dialects.ts +6 -2
- package/src/lang/en/index.ts +781 -117
- package/src/lang/es/index.ts +85 -9
- package/src/lang/fi/index.ts +6 -2
- package/src/lang/zh/index.ts +44 -18
- package/types/core/ir.d.ts +1 -0
- package/types/core/util.d.ts +10 -1
package/dist/lang/es.cjs
CHANGED
|
@@ -72,6 +72,26 @@ function arithmeticStep(values) {
|
|
|
72
72
|
}
|
|
73
73
|
return { start: values[0], interval, last: values[values.length - 1] };
|
|
74
74
|
}
|
|
75
|
+
function weekdayDisplayKey(value) {
|
|
76
|
+
return value === 0 ? 7 : value;
|
|
77
|
+
}
|
|
78
|
+
function orderWeekdaysForDisplay(segments) {
|
|
79
|
+
const flattened = segments.flatMap(function flat(segment) {
|
|
80
|
+
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
81
|
+
return { kind: "single", value: "" + value };
|
|
82
|
+
}) : [segment];
|
|
83
|
+
});
|
|
84
|
+
function key(segment) {
|
|
85
|
+
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
86
|
+
}
|
|
87
|
+
return flattened.map(function index(segment, position) {
|
|
88
|
+
return [segment, position];
|
|
89
|
+
}).sort(function byDisplayKey(a, b) {
|
|
90
|
+
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
91
|
+
}).map(function unwrap(pair) {
|
|
92
|
+
return pair[0];
|
|
93
|
+
});
|
|
94
|
+
}
|
|
75
95
|
function toFieldNumber(token, numberMap) {
|
|
76
96
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
77
97
|
}
|
|
@@ -224,7 +244,7 @@ function renderComposeSeconds(ir, plan, opts) {
|
|
|
224
244
|
}
|
|
225
245
|
if (plan.rest.kind === "hourRange" && ir.shapes.second === "step" && ir.pattern.weekday !== "*") {
|
|
226
246
|
const restNode = plan.rest;
|
|
227
|
-
const window = hourWindow(restNode, opts);
|
|
247
|
+
const window = hourWindow(boundedWindow(restNode), opts);
|
|
228
248
|
const dayFrame = weekdayQualifier(ir) + monthScope(ir);
|
|
229
249
|
const cadence = "cada " + numero(stepSegment(ir.analyses.segments.second).interval, opts) + " segundos del minuto " + ir.pattern.minute;
|
|
230
250
|
return dayFrame + ", " + window + ", " + cadence;
|
|
@@ -437,7 +457,8 @@ function renderHourStep(ir, plan, opts) {
|
|
|
437
457
|
return stepHours(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
|
|
438
458
|
}
|
|
439
459
|
function boundedWindow(plan) {
|
|
440
|
-
|
|
460
|
+
const last = plan.minuteForm === "wildcard" ? plan.boundMinute ?? 0 : 0;
|
|
461
|
+
return { from: plan.from, last, to: plan.to };
|
|
441
462
|
}
|
|
442
463
|
function hourWindow(window, opts) {
|
|
443
464
|
return timeRange(
|
|
@@ -481,7 +502,7 @@ function dowArm(ir) {
|
|
|
481
502
|
if (quartz) {
|
|
482
503
|
return quartz;
|
|
483
504
|
}
|
|
484
|
-
const segments =
|
|
505
|
+
const segments = orderWeekdaysForDisplay(fieldSegments(ir, "weekday"));
|
|
485
506
|
const allSingles = segments.every(function single(segment) {
|
|
486
507
|
return segment.kind === "single";
|
|
487
508
|
});
|
|
@@ -705,7 +726,7 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
705
726
|
return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
|
|
706
727
|
}
|
|
707
728
|
const cadence = unevenHourCadence(ir, opts);
|
|
708
|
-
const phrase = cadence ? minutesList(ir, opts) + ", " + cadence + trailingQualifier(ir, opts) : minutesList(ir, opts) + ", " +
|
|
729
|
+
const phrase = cadence ? minutesList(ir, opts) + ", " + cadence + trailingQualifier(ir, opts) : minutesList(ir, opts) + ", " + hourContextTimes(ir, opts) + trailingQualifier(ir, opts);
|
|
709
730
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
|
|
710
731
|
}
|
|
711
732
|
var renderers = {
|
|
@@ -896,6 +917,48 @@ function hourRangeCadence(ir, minute, opts) {
|
|
|
896
917
|
}
|
|
897
918
|
return hourCadenceLead(ir, minute, opts) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
898
919
|
}
|
|
920
|
+
function hourContextTimes(ir, opts) {
|
|
921
|
+
const segments = hourSegments(ir);
|
|
922
|
+
const points = [];
|
|
923
|
+
const hasRange = segments.some(function range(segment) {
|
|
924
|
+
return segment.kind === "range";
|
|
925
|
+
});
|
|
926
|
+
segments.forEach(function collect(segment) {
|
|
927
|
+
if (segment.kind === "step") {
|
|
928
|
+
points.push(...segment.fires);
|
|
929
|
+
} else if (segment.kind === "single") {
|
|
930
|
+
points.push(+segment.value);
|
|
931
|
+
}
|
|
932
|
+
});
|
|
933
|
+
function isWord(hour) {
|
|
934
|
+
return !opts.ampm && (hour === 0 || hour === 12);
|
|
935
|
+
}
|
|
936
|
+
if (!hasRange && points.every(isWord)) {
|
|
937
|
+
return joinList(points.map(function each(hour) {
|
|
938
|
+
return atTime(bareHourPhrase(hour, opts));
|
|
939
|
+
}));
|
|
940
|
+
}
|
|
941
|
+
function wholeHour(hour) {
|
|
942
|
+
return "de la hora " + fromTime(explicitTimePhrase(hour, 0, opts));
|
|
943
|
+
}
|
|
944
|
+
const pieces = [];
|
|
945
|
+
segments.forEach(function place(segment) {
|
|
946
|
+
if (segment.kind === "range") {
|
|
947
|
+
pieces.push(timeRange(
|
|
948
|
+
{ hour: +segment.bounds[0], minute: 0 },
|
|
949
|
+
{ hour: +segment.bounds[1], minute: 0 },
|
|
950
|
+
opts
|
|
951
|
+
));
|
|
952
|
+
} else if (segment.kind === "step") {
|
|
953
|
+
segment.fires.forEach(function each(hour) {
|
|
954
|
+
pieces.push(wholeHour(hour));
|
|
955
|
+
});
|
|
956
|
+
} else {
|
|
957
|
+
pieces.push(wholeHour(+segment.value));
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
return joinList(pieces);
|
|
961
|
+
}
|
|
899
962
|
function atTimes(hours, opts) {
|
|
900
963
|
return hours.map(function each(hour) {
|
|
901
964
|
return atTime(timePhrase(hour, 0, null, opts));
|
|
@@ -1158,7 +1221,7 @@ function weekdayQualifier(ir) {
|
|
|
1158
1221
|
if (quartz) {
|
|
1159
1222
|
return quartz;
|
|
1160
1223
|
}
|
|
1161
|
-
const segments =
|
|
1224
|
+
const segments = orderWeekdaysForDisplay(fieldSegments(ir, "weekday"));
|
|
1162
1225
|
const allSingles = segments.every(function single(segment) {
|
|
1163
1226
|
return segment.kind === "single";
|
|
1164
1227
|
});
|
package/dist/lang/es.js
CHANGED
|
@@ -46,6 +46,26 @@ function arithmeticStep(values) {
|
|
|
46
46
|
}
|
|
47
47
|
return { start: values[0], interval, last: values[values.length - 1] };
|
|
48
48
|
}
|
|
49
|
+
function weekdayDisplayKey(value) {
|
|
50
|
+
return value === 0 ? 7 : value;
|
|
51
|
+
}
|
|
52
|
+
function orderWeekdaysForDisplay(segments) {
|
|
53
|
+
const flattened = segments.flatMap(function flat(segment) {
|
|
54
|
+
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
55
|
+
return { kind: "single", value: "" + value };
|
|
56
|
+
}) : [segment];
|
|
57
|
+
});
|
|
58
|
+
function key(segment) {
|
|
59
|
+
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
60
|
+
}
|
|
61
|
+
return flattened.map(function index(segment, position) {
|
|
62
|
+
return [segment, position];
|
|
63
|
+
}).sort(function byDisplayKey(a, b) {
|
|
64
|
+
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
65
|
+
}).map(function unwrap(pair) {
|
|
66
|
+
return pair[0];
|
|
67
|
+
});
|
|
68
|
+
}
|
|
49
69
|
function toFieldNumber(token, numberMap) {
|
|
50
70
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
51
71
|
}
|
|
@@ -198,7 +218,7 @@ function renderComposeSeconds(ir, plan, opts) {
|
|
|
198
218
|
}
|
|
199
219
|
if (plan.rest.kind === "hourRange" && ir.shapes.second === "step" && ir.pattern.weekday !== "*") {
|
|
200
220
|
const restNode = plan.rest;
|
|
201
|
-
const window = hourWindow(restNode, opts);
|
|
221
|
+
const window = hourWindow(boundedWindow(restNode), opts);
|
|
202
222
|
const dayFrame = weekdayQualifier(ir) + monthScope(ir);
|
|
203
223
|
const cadence = "cada " + numero(stepSegment(ir.analyses.segments.second).interval, opts) + " segundos del minuto " + ir.pattern.minute;
|
|
204
224
|
return dayFrame + ", " + window + ", " + cadence;
|
|
@@ -411,7 +431,8 @@ function renderHourStep(ir, plan, opts) {
|
|
|
411
431
|
return stepHours(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
|
|
412
432
|
}
|
|
413
433
|
function boundedWindow(plan) {
|
|
414
|
-
|
|
434
|
+
const last = plan.minuteForm === "wildcard" ? plan.boundMinute ?? 0 : 0;
|
|
435
|
+
return { from: plan.from, last, to: plan.to };
|
|
415
436
|
}
|
|
416
437
|
function hourWindow(window, opts) {
|
|
417
438
|
return timeRange(
|
|
@@ -455,7 +476,7 @@ function dowArm(ir) {
|
|
|
455
476
|
if (quartz) {
|
|
456
477
|
return quartz;
|
|
457
478
|
}
|
|
458
|
-
const segments =
|
|
479
|
+
const segments = orderWeekdaysForDisplay(fieldSegments(ir, "weekday"));
|
|
459
480
|
const allSingles = segments.every(function single(segment) {
|
|
460
481
|
return segment.kind === "single";
|
|
461
482
|
});
|
|
@@ -679,7 +700,7 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
679
700
|
return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
|
|
680
701
|
}
|
|
681
702
|
const cadence = unevenHourCadence(ir, opts);
|
|
682
|
-
const phrase = cadence ? minutesList(ir, opts) + ", " + cadence + trailingQualifier(ir, opts) : minutesList(ir, opts) + ", " +
|
|
703
|
+
const phrase = cadence ? minutesList(ir, opts) + ", " + cadence + trailingQualifier(ir, opts) : minutesList(ir, opts) + ", " + hourContextTimes(ir, opts) + trailingQualifier(ir, opts);
|
|
683
704
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
|
|
684
705
|
}
|
|
685
706
|
var renderers = {
|
|
@@ -870,6 +891,48 @@ function hourRangeCadence(ir, minute, opts) {
|
|
|
870
891
|
}
|
|
871
892
|
return hourCadenceLead(ir, minute, opts) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
872
893
|
}
|
|
894
|
+
function hourContextTimes(ir, opts) {
|
|
895
|
+
const segments = hourSegments(ir);
|
|
896
|
+
const points = [];
|
|
897
|
+
const hasRange = segments.some(function range(segment) {
|
|
898
|
+
return segment.kind === "range";
|
|
899
|
+
});
|
|
900
|
+
segments.forEach(function collect(segment) {
|
|
901
|
+
if (segment.kind === "step") {
|
|
902
|
+
points.push(...segment.fires);
|
|
903
|
+
} else if (segment.kind === "single") {
|
|
904
|
+
points.push(+segment.value);
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
function isWord(hour) {
|
|
908
|
+
return !opts.ampm && (hour === 0 || hour === 12);
|
|
909
|
+
}
|
|
910
|
+
if (!hasRange && points.every(isWord)) {
|
|
911
|
+
return joinList(points.map(function each(hour) {
|
|
912
|
+
return atTime(bareHourPhrase(hour, opts));
|
|
913
|
+
}));
|
|
914
|
+
}
|
|
915
|
+
function wholeHour(hour) {
|
|
916
|
+
return "de la hora " + fromTime(explicitTimePhrase(hour, 0, opts));
|
|
917
|
+
}
|
|
918
|
+
const pieces = [];
|
|
919
|
+
segments.forEach(function place(segment) {
|
|
920
|
+
if (segment.kind === "range") {
|
|
921
|
+
pieces.push(timeRange(
|
|
922
|
+
{ hour: +segment.bounds[0], minute: 0 },
|
|
923
|
+
{ hour: +segment.bounds[1], minute: 0 },
|
|
924
|
+
opts
|
|
925
|
+
));
|
|
926
|
+
} else if (segment.kind === "step") {
|
|
927
|
+
segment.fires.forEach(function each(hour) {
|
|
928
|
+
pieces.push(wholeHour(hour));
|
|
929
|
+
});
|
|
930
|
+
} else {
|
|
931
|
+
pieces.push(wholeHour(+segment.value));
|
|
932
|
+
}
|
|
933
|
+
});
|
|
934
|
+
return joinList(pieces);
|
|
935
|
+
}
|
|
873
936
|
function atTimes(hours, opts) {
|
|
874
937
|
return hours.map(function each(hour) {
|
|
875
938
|
return atTime(timePhrase(hour, 0, null, opts));
|
|
@@ -1132,7 +1195,7 @@ function weekdayQualifier(ir) {
|
|
|
1132
1195
|
if (quartz) {
|
|
1133
1196
|
return quartz;
|
|
1134
1197
|
}
|
|
1135
|
-
const segments =
|
|
1198
|
+
const segments = orderWeekdaysForDisplay(fieldSegments(ir, "weekday"));
|
|
1136
1199
|
const allSingles = segments.every(function single(segment) {
|
|
1137
1200
|
return segment.kind === "single";
|
|
1138
1201
|
});
|
package/dist/lang/fi.cjs
CHANGED
|
@@ -72,6 +72,26 @@ function arithmeticStep(values) {
|
|
|
72
72
|
}
|
|
73
73
|
return { start: values[0], interval, last: values[values.length - 1] };
|
|
74
74
|
}
|
|
75
|
+
function weekdayDisplayKey(value) {
|
|
76
|
+
return value === 0 ? 7 : value;
|
|
77
|
+
}
|
|
78
|
+
function orderWeekdaysForDisplay(segments) {
|
|
79
|
+
const flattened = segments.flatMap(function flat(segment) {
|
|
80
|
+
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
81
|
+
return { kind: "single", value: "" + value };
|
|
82
|
+
}) : [segment];
|
|
83
|
+
});
|
|
84
|
+
function key(segment) {
|
|
85
|
+
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
86
|
+
}
|
|
87
|
+
return flattened.map(function index(segment, position) {
|
|
88
|
+
return [segment, position];
|
|
89
|
+
}).sort(function byDisplayKey(a, b) {
|
|
90
|
+
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
91
|
+
}).map(function unwrap(pair) {
|
|
92
|
+
return pair[0];
|
|
93
|
+
});
|
|
94
|
+
}
|
|
75
95
|
function toFieldNumber(token, numberMap) {
|
|
76
96
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
77
97
|
}
|
|
@@ -965,7 +985,7 @@ function weekdayQualifier(ir) {
|
|
|
965
985
|
if (quartz) {
|
|
966
986
|
return quartz;
|
|
967
987
|
}
|
|
968
|
-
const segments =
|
|
988
|
+
const segments = orderWeekdaysForDisplay(ir.analyses.segments.weekday);
|
|
969
989
|
return joinList(segments.map(function piece(segment) {
|
|
970
990
|
if (segment.kind === "range") {
|
|
971
991
|
return weekdays[weekdayNumber(segment.bounds[0])].ela + " " + weekdays[weekdayNumber(segment.bounds[1])].ill;
|
package/dist/lang/fi.js
CHANGED
|
@@ -46,6 +46,26 @@ function arithmeticStep(values) {
|
|
|
46
46
|
}
|
|
47
47
|
return { start: values[0], interval, last: values[values.length - 1] };
|
|
48
48
|
}
|
|
49
|
+
function weekdayDisplayKey(value) {
|
|
50
|
+
return value === 0 ? 7 : value;
|
|
51
|
+
}
|
|
52
|
+
function orderWeekdaysForDisplay(segments) {
|
|
53
|
+
const flattened = segments.flatMap(function flat(segment) {
|
|
54
|
+
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
55
|
+
return { kind: "single", value: "" + value };
|
|
56
|
+
}) : [segment];
|
|
57
|
+
});
|
|
58
|
+
function key(segment) {
|
|
59
|
+
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
60
|
+
}
|
|
61
|
+
return flattened.map(function index(segment, position) {
|
|
62
|
+
return [segment, position];
|
|
63
|
+
}).sort(function byDisplayKey(a, b) {
|
|
64
|
+
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
65
|
+
}).map(function unwrap(pair) {
|
|
66
|
+
return pair[0];
|
|
67
|
+
});
|
|
68
|
+
}
|
|
49
69
|
function toFieldNumber(token, numberMap) {
|
|
50
70
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
51
71
|
}
|
|
@@ -939,7 +959,7 @@ function weekdayQualifier(ir) {
|
|
|
939
959
|
if (quartz) {
|
|
940
960
|
return quartz;
|
|
941
961
|
}
|
|
942
|
-
const segments =
|
|
962
|
+
const segments = orderWeekdaysForDisplay(ir.analyses.segments.weekday);
|
|
943
963
|
return joinList(segments.map(function piece(segment) {
|
|
944
964
|
if (segment.kind === "range") {
|
|
945
965
|
return weekdays[weekdayNumber(segment.bounds[0])].ela + " " + weekdays[weekdayNumber(segment.bounds[1])].ill;
|
package/dist/lang/zh.cjs
CHANGED
|
@@ -44,6 +44,26 @@ function arithmeticStep(values) {
|
|
|
44
44
|
}
|
|
45
45
|
return { start: values[0], interval, last: values[values.length - 1] };
|
|
46
46
|
}
|
|
47
|
+
function weekdayDisplayKey(value) {
|
|
48
|
+
return value === 0 ? 7 : value;
|
|
49
|
+
}
|
|
50
|
+
function orderWeekdaysForDisplay(segments) {
|
|
51
|
+
const flattened = segments.flatMap(function flat(segment) {
|
|
52
|
+
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
53
|
+
return { kind: "single", value: "" + value };
|
|
54
|
+
}) : [segment];
|
|
55
|
+
});
|
|
56
|
+
function key(segment) {
|
|
57
|
+
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
58
|
+
}
|
|
59
|
+
return flattened.map(function index(segment, position) {
|
|
60
|
+
return [segment, position];
|
|
61
|
+
}).sort(function byDisplayKey(a, b) {
|
|
62
|
+
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
63
|
+
}).map(function unwrap(pair) {
|
|
64
|
+
return pair[0];
|
|
65
|
+
});
|
|
66
|
+
}
|
|
47
67
|
function toFieldNumber(token, numberMap) {
|
|
48
68
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
49
69
|
}
|
|
@@ -384,6 +404,15 @@ function hourCadencePhrase(ir) {
|
|
|
384
404
|
anchor: ""
|
|
385
405
|
});
|
|
386
406
|
}
|
|
407
|
+
function minuteZeroConfinement(ir, stride, prefix) {
|
|
408
|
+
if (stride.interval === 2 && stride.start === 0) {
|
|
409
|
+
return "\u5728\u5076\u6570\u5C0F\u65F60\u5206" + secondTail(ir);
|
|
410
|
+
}
|
|
411
|
+
if (prefix.indexOf("\u4ECE") !== -1) {
|
|
412
|
+
return prefix + "0\u5206" + secondTail(ir);
|
|
413
|
+
}
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
387
416
|
function hourCadence(ir) {
|
|
388
417
|
const stride = hourStride(ir);
|
|
389
418
|
if (!stride) {
|
|
@@ -400,7 +429,7 @@ function hourCadence(ir) {
|
|
|
400
429
|
const minute = +ir.pattern.minute;
|
|
401
430
|
const subMinute = ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
402
431
|
if (minute === 0 && subMinute) {
|
|
403
|
-
return
|
|
432
|
+
return minuteZeroConfinement(ir, stride, prefix);
|
|
404
433
|
}
|
|
405
434
|
if (minute === 0) {
|
|
406
435
|
return prefix + "0\u5206" + secondTail(ir);
|
|
@@ -634,7 +663,7 @@ function quartzDate(token, monthPrefix) {
|
|
|
634
663
|
if (token.startsWith("L-")) {
|
|
635
664
|
return monthPrefix + "\u6700\u540E\u7B2C" + token.slice(2) + "\u5929";
|
|
636
665
|
}
|
|
637
|
-
return "\u6700\u63A5\u8FD1" + token.slice(0, -1) + "\u65E5\u7684\u5DE5\u4F5C\u65E5";
|
|
666
|
+
return monthPrefix + "\u6700\u63A5\u8FD1" + token.slice(0, -1) + "\u65E5\u7684\u5DE5\u4F5C\u65E5";
|
|
638
667
|
}
|
|
639
668
|
function datePhrase(ir) {
|
|
640
669
|
const month = monthPhrase(ir);
|
|
@@ -648,7 +677,11 @@ function datePhrase(ir) {
|
|
|
648
677
|
if (ir.shapes.date === "step") {
|
|
649
678
|
return month + cadence(stepSegment(ir, "date").interval, "\u5929");
|
|
650
679
|
}
|
|
651
|
-
|
|
680
|
+
if (!month) {
|
|
681
|
+
return "\u6BCF\u6708" + dayList(ir);
|
|
682
|
+
}
|
|
683
|
+
const monthMulti = ir.shapes.month === "range" || ir.shapes.month === "list";
|
|
684
|
+
return month + (monthMulti ? "\uFF0C" : "") + dayList(ir);
|
|
652
685
|
}
|
|
653
686
|
function dateCore(ir, quartzPrefix) {
|
|
654
687
|
if (ir.shapes.date === "quartz") {
|
|
@@ -690,10 +723,8 @@ function weekdayPhrase(ir, orContext, monthPrefix) {
|
|
|
690
723
|
return "\u6BCF" + weekdayName(from) + "\u81F3" + weekdayName(to);
|
|
691
724
|
}
|
|
692
725
|
const days = [];
|
|
693
|
-
segs.forEach(function expand(seg) {
|
|
694
|
-
if (seg.kind === "
|
|
695
|
-
days.push(...seg.fires);
|
|
696
|
-
} else if (seg.kind === "single") {
|
|
726
|
+
orderWeekdaysForDisplay(segs).forEach(function expand(seg) {
|
|
727
|
+
if (seg.kind === "single") {
|
|
697
728
|
days.push(toFieldNumber(seg.value, weekdayNumbers));
|
|
698
729
|
}
|
|
699
730
|
});
|
package/dist/lang/zh.js
CHANGED
|
@@ -18,6 +18,26 @@ function arithmeticStep(values) {
|
|
|
18
18
|
}
|
|
19
19
|
return { start: values[0], interval, last: values[values.length - 1] };
|
|
20
20
|
}
|
|
21
|
+
function weekdayDisplayKey(value) {
|
|
22
|
+
return value === 0 ? 7 : value;
|
|
23
|
+
}
|
|
24
|
+
function orderWeekdaysForDisplay(segments) {
|
|
25
|
+
const flattened = segments.flatMap(function flat(segment) {
|
|
26
|
+
return segment.kind === "step" ? segment.fires.map(function single(value) {
|
|
27
|
+
return { kind: "single", value: "" + value };
|
|
28
|
+
}) : [segment];
|
|
29
|
+
});
|
|
30
|
+
function key(segment) {
|
|
31
|
+
return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
|
|
32
|
+
}
|
|
33
|
+
return flattened.map(function index(segment, position) {
|
|
34
|
+
return [segment, position];
|
|
35
|
+
}).sort(function byDisplayKey(a, b) {
|
|
36
|
+
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
37
|
+
}).map(function unwrap(pair) {
|
|
38
|
+
return pair[0];
|
|
39
|
+
});
|
|
40
|
+
}
|
|
21
41
|
function toFieldNumber(token, numberMap) {
|
|
22
42
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
23
43
|
}
|
|
@@ -358,6 +378,15 @@ function hourCadencePhrase(ir) {
|
|
|
358
378
|
anchor: ""
|
|
359
379
|
});
|
|
360
380
|
}
|
|
381
|
+
function minuteZeroConfinement(ir, stride, prefix) {
|
|
382
|
+
if (stride.interval === 2 && stride.start === 0) {
|
|
383
|
+
return "\u5728\u5076\u6570\u5C0F\u65F60\u5206" + secondTail(ir);
|
|
384
|
+
}
|
|
385
|
+
if (prefix.indexOf("\u4ECE") !== -1) {
|
|
386
|
+
return prefix + "0\u5206" + secondTail(ir);
|
|
387
|
+
}
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
361
390
|
function hourCadence(ir) {
|
|
362
391
|
const stride = hourStride(ir);
|
|
363
392
|
if (!stride) {
|
|
@@ -374,7 +403,7 @@ function hourCadence(ir) {
|
|
|
374
403
|
const minute = +ir.pattern.minute;
|
|
375
404
|
const subMinute = ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
376
405
|
if (minute === 0 && subMinute) {
|
|
377
|
-
return
|
|
406
|
+
return minuteZeroConfinement(ir, stride, prefix);
|
|
378
407
|
}
|
|
379
408
|
if (minute === 0) {
|
|
380
409
|
return prefix + "0\u5206" + secondTail(ir);
|
|
@@ -608,7 +637,7 @@ function quartzDate(token, monthPrefix) {
|
|
|
608
637
|
if (token.startsWith("L-")) {
|
|
609
638
|
return monthPrefix + "\u6700\u540E\u7B2C" + token.slice(2) + "\u5929";
|
|
610
639
|
}
|
|
611
|
-
return "\u6700\u63A5\u8FD1" + token.slice(0, -1) + "\u65E5\u7684\u5DE5\u4F5C\u65E5";
|
|
640
|
+
return monthPrefix + "\u6700\u63A5\u8FD1" + token.slice(0, -1) + "\u65E5\u7684\u5DE5\u4F5C\u65E5";
|
|
612
641
|
}
|
|
613
642
|
function datePhrase(ir) {
|
|
614
643
|
const month = monthPhrase(ir);
|
|
@@ -622,7 +651,11 @@ function datePhrase(ir) {
|
|
|
622
651
|
if (ir.shapes.date === "step") {
|
|
623
652
|
return month + cadence(stepSegment(ir, "date").interval, "\u5929");
|
|
624
653
|
}
|
|
625
|
-
|
|
654
|
+
if (!month) {
|
|
655
|
+
return "\u6BCF\u6708" + dayList(ir);
|
|
656
|
+
}
|
|
657
|
+
const monthMulti = ir.shapes.month === "range" || ir.shapes.month === "list";
|
|
658
|
+
return month + (monthMulti ? "\uFF0C" : "") + dayList(ir);
|
|
626
659
|
}
|
|
627
660
|
function dateCore(ir, quartzPrefix) {
|
|
628
661
|
if (ir.shapes.date === "quartz") {
|
|
@@ -664,10 +697,8 @@ function weekdayPhrase(ir, orContext, monthPrefix) {
|
|
|
664
697
|
return "\u6BCF" + weekdayName(from) + "\u81F3" + weekdayName(to);
|
|
665
698
|
}
|
|
666
699
|
const days = [];
|
|
667
|
-
segs.forEach(function expand(seg) {
|
|
668
|
-
if (seg.kind === "
|
|
669
|
-
days.push(...seg.fires);
|
|
670
|
-
} else if (seg.kind === "single") {
|
|
700
|
+
orderWeekdaysForDisplay(segs).forEach(function expand(seg) {
|
|
701
|
+
if (seg.kind === "single") {
|
|
671
702
|
days.push(toFieldNumber(seg.value, weekdayNumbers));
|
|
672
703
|
}
|
|
673
704
|
});
|
package/package.json
CHANGED
package/src/core/ir.ts
CHANGED
|
@@ -132,6 +132,11 @@ export interface DialectStyle {
|
|
|
132
132
|
sep: string;
|
|
133
133
|
serialComma: boolean;
|
|
134
134
|
through: string;
|
|
135
|
+
// Whether a contiguous hour range reads as an up-to-but-not-including
|
|
136
|
+
// window ("from 9 a.m. until 6 p.m.") rather than a "through <last fire>"
|
|
137
|
+
// span. Set only on the default English dialect; other dialects and custom
|
|
138
|
+
// styles keep the "through" span.
|
|
139
|
+
untilWindow?: boolean;
|
|
135
140
|
}
|
|
136
141
|
|
|
137
142
|
/**
|
package/src/core/util.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Small shared utilities for the core.
|
|
2
2
|
|
|
3
|
+
import type {Segment} from './ir.js';
|
|
4
|
+
|
|
3
5
|
function includes(str: string | number, sub: string): boolean {
|
|
4
6
|
return ('' + str).indexOf(sub) !== -1;
|
|
5
7
|
}
|
|
@@ -44,6 +46,54 @@ function arithmeticStep(values: number[]):
|
|
|
44
46
|
return {start: values[0], interval, last: values[values.length - 1]};
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
// The display sort key for a canonical weekday number: Monday (1) first,
|
|
50
|
+
// Sunday (0) last. The IR keeps Sunday=0 canonical; this is display-only.
|
|
51
|
+
function weekdayDisplayKey(value: number): number {
|
|
52
|
+
return value === 0 ? 7 : value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// A weekday display segment: a single day or a (possibly wrap) range. Steps
|
|
56
|
+
// are flattened away into singles before sorting, so the result is only these
|
|
57
|
+
// two kinds; each renderer turns them into names exactly as it does today.
|
|
58
|
+
type WeekdaySegment =
|
|
59
|
+
| {kind: 'single'; value: string}
|
|
60
|
+
| {kind: 'range'; bounds: [string, string]};
|
|
61
|
+
|
|
62
|
+
// Reorder weekday segments Monday-first (Sunday last) for display, so a weekend
|
|
63
|
+
// list reads "Saturday and Sunday" rather than the canonical Sunday-first
|
|
64
|
+
// "Sunday and Saturday". Display-only: the IR / canonical order is unchanged (a
|
|
65
|
+
// fresh array is returned). A step expands to its fires as singles so the days
|
|
66
|
+
// sort into the list; a range stays one unit and keeps its own bounds order (a
|
|
67
|
+
// wrap range is not reordered into a list), sorting by its opening bound — so a
|
|
68
|
+
// lone range sorts to a one-element list and is unchanged. The sort is stable,
|
|
69
|
+
// so equal opening days keep input order.
|
|
70
|
+
function orderWeekdaysForDisplay(segments: Segment[]): WeekdaySegment[] {
|
|
71
|
+
const flattened: WeekdaySegment[] = segments.flatMap(function flat(segment) {
|
|
72
|
+
return segment.kind === 'step' ?
|
|
73
|
+
segment.fires.map(function single(value): WeekdaySegment {
|
|
74
|
+
return {kind: 'single', value: '' + value};
|
|
75
|
+
}) :
|
|
76
|
+
[segment];
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
function key(segment: WeekdaySegment): number {
|
|
80
|
+
return segment.kind === 'range' ?
|
|
81
|
+
weekdayDisplayKey(+segment.bounds[0]) :
|
|
82
|
+
weekdayDisplayKey(+segment.value);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return flattened
|
|
86
|
+
.map(function index(segment, position): [WeekdaySegment, number] {
|
|
87
|
+
return [segment, position];
|
|
88
|
+
})
|
|
89
|
+
.sort(function byDisplayKey(a, b): number {
|
|
90
|
+
return key(a[0]) - key(b[0]) || a[1] - b[1];
|
|
91
|
+
})
|
|
92
|
+
.map(function unwrap(pair): WeekdaySegment {
|
|
93
|
+
return pair[0];
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
47
97
|
// Resolve a numeric or named field token (e.g. '5' or 'FRI') to its number.
|
|
48
98
|
function toFieldNumber(
|
|
49
99
|
token: string,
|
|
@@ -54,5 +104,6 @@ function toFieldNumber(
|
|
|
54
104
|
return isNonNegativeInteger(token) ? +token : numberMap![token.toUpperCase()];
|
|
55
105
|
}
|
|
56
106
|
export {
|
|
57
|
-
arithmeticStep, includes, isNonNegativeInteger,
|
|
107
|
+
arithmeticStep, includes, isNonNegativeInteger, orderWeekdaysForDisplay,
|
|
108
|
+
toFieldNumber, unique
|
|
58
109
|
};
|