cronli5 0.1.5 → 0.1.7
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 +71 -0
- package/README.md +2 -2
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +156 -27
- package/dist/cronli5.js +156 -27
- package/dist/lang/de.cjs +157 -36
- package/dist/lang/de.js +157 -36
- package/dist/lang/en.cjs +156 -27
- package/dist/lang/en.js +156 -27
- package/dist/lang/es.cjs +156 -18
- package/dist/lang/es.js +156 -18
- package/dist/lang/fi.cjs +128 -20
- package/dist/lang/fi.js +128 -20
- package/dist/lang/zh.cjs +126 -58
- package/dist/lang/zh.js +126 -58
- package/package.json +2 -2
- package/src/core/util.ts +52 -1
- package/src/lang/de/index.ts +331 -74
- package/src/lang/en/index.ts +327 -62
- package/src/lang/es/index.ts +306 -39
- package/src/lang/fi/index.ts +251 -41
- package/src/lang/zh/index.ts +246 -105
- package/types/core/util.d.ts +10 -1
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
|
}
|
|
@@ -249,8 +269,18 @@ function minuteHourClause(ir) {
|
|
|
249
269
|
function renderMinutePast(ir) {
|
|
250
270
|
return minuteHourClause(ir);
|
|
251
271
|
}
|
|
272
|
+
function hourSegmentWords(segment) {
|
|
273
|
+
if (segment.kind === "range") {
|
|
274
|
+
return [hourWord(+segment.bounds[0]) + "\u81F3" + hourWord(+segment.bounds[1])];
|
|
275
|
+
}
|
|
276
|
+
if (segment.kind === "step") {
|
|
277
|
+
return segment.fires.map(hourWord);
|
|
278
|
+
}
|
|
279
|
+
return [hourWord(+segment.value)];
|
|
280
|
+
}
|
|
252
281
|
function hourList(ir) {
|
|
253
|
-
|
|
282
|
+
const words = fieldSegments(ir, "hour").flatMap(hourSegmentWords);
|
|
283
|
+
return joinAnd(words);
|
|
254
284
|
}
|
|
255
285
|
function hourFrame(ir) {
|
|
256
286
|
if (ir.shapes.hour === "range") {
|
|
@@ -263,9 +293,11 @@ function renderMinuteFrequency(ir, plan) {
|
|
|
263
293
|
const minuteStep = stepSegment(ir, "minute");
|
|
264
294
|
const base = stepClause(minuteStep, UNITS.minute, "\u5206", "\u6BCF\u5C0F\u65F6");
|
|
265
295
|
const { hours } = plan;
|
|
266
|
-
if (hours.kind === "step") {
|
|
267
|
-
const
|
|
268
|
-
|
|
296
|
+
if (hours.kind === "step" || hours.kind === "during") {
|
|
297
|
+
const hourCad = hourCadencePhrase(ir);
|
|
298
|
+
if (hourCad !== null) {
|
|
299
|
+
return hourCad + (hourCad.indexOf("\u81F3") === -1 ? "" : "\uFF0C") + base;
|
|
300
|
+
}
|
|
269
301
|
}
|
|
270
302
|
if (hours.kind === "single" || hours.kind === "window" && hours.from === hours.to) {
|
|
271
303
|
return "\u5728" + hourWord(hours.from) + "\u81F3" + hours.from + "\u70B9" + hours.last + "\u5206\u4E4B\u95F4\uFF0C" + base;
|
|
@@ -287,20 +319,21 @@ function renderMinuteSpanInHour(ir, plan) {
|
|
|
287
319
|
}
|
|
288
320
|
function renderMinutesAcrossHours(ir, plan) {
|
|
289
321
|
const { form } = plan;
|
|
322
|
+
const hourCad = hourCadencePhrase(ir);
|
|
290
323
|
if (form === "wildcard") {
|
|
291
|
-
return "\u5728" + hourList(ir) + "\uFF0C\u6BCF\u5206\u949F";
|
|
324
|
+
return hourCad === null ? "\u5728" + hourList(ir) + "\uFF0C\u6BCF\u5206\u949F" : hourCad + "\uFF0C\u6BCF\u5206\u949F";
|
|
292
325
|
}
|
|
293
|
-
return hourList(ir) + "\uFF0C" + minuteHourClause(ir) + "\uFF0C\u6BCF\u5206\u949F";
|
|
326
|
+
return (hourCad ?? hourList(ir)) + "\uFF0C" + minuteHourClause(ir) + "\uFF0C\u6BCF\u5206\u949F";
|
|
294
327
|
}
|
|
295
328
|
function renderMinuteSpanAcrossHourStep(ir, plan) {
|
|
296
329
|
const hourStep = stepSegment(ir, "hour");
|
|
297
330
|
const { form } = plan;
|
|
298
331
|
if (form === "list") {
|
|
299
|
-
return
|
|
332
|
+
return hourCadencePhrase(ir) + "\uFF0C" + renderMinutePast(ir);
|
|
300
333
|
}
|
|
301
334
|
const minuteTail = form === "wildcard" ? "\u6BCF\u5206\u949F" : minuteHourClause(ir) + "\uFF0C\u6BCF\u5206\u949F";
|
|
302
335
|
if (hourStep.startToken !== "*") {
|
|
303
|
-
return
|
|
336
|
+
return hourCadencePhrase(ir) + "\uFF0C" + minuteTail;
|
|
304
337
|
}
|
|
305
338
|
if (hourStep.interval === 2 && form === "wildcard") {
|
|
306
339
|
return "\u5728\u5076\u6570\u5C0F\u65F6\uFF0C" + minuteTail;
|
|
@@ -309,26 +342,26 @@ function renderMinuteSpanAcrossHourStep(ir, plan) {
|
|
|
309
342
|
return form === "wildcard" ? cad + "\u5185\uFF0C" + minuteTail : cad + "\uFF0C" + minuteTail;
|
|
310
343
|
}
|
|
311
344
|
function renderClockTimes(ir, plan, opts) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
return cad;
|
|
316
|
-
}
|
|
345
|
+
const cad = hourCadenceText(ir);
|
|
346
|
+
if (cad !== null) {
|
|
347
|
+
return cad;
|
|
317
348
|
}
|
|
318
349
|
const { times } = plan;
|
|
319
350
|
return joinAnd(times.map((t) => clockTime(t.hour, t.minute, t.second, opts)));
|
|
320
351
|
}
|
|
321
352
|
function renderCompactClockTimes(ir, plan) {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
return cad;
|
|
326
|
-
}
|
|
353
|
+
const cad = hourCadenceText(ir);
|
|
354
|
+
if (cad !== null) {
|
|
355
|
+
return cad;
|
|
327
356
|
}
|
|
328
|
-
const
|
|
357
|
+
const compact = plan;
|
|
329
358
|
const secs = fieldSegments(ir, "second");
|
|
330
359
|
const tail = secs.length && ir.pattern.second !== "0" ? "\uFF0C\u7B2C" + valueText(secs) + "\u79D2" : "";
|
|
331
|
-
if (
|
|
360
|
+
if (!compact.fold) {
|
|
361
|
+
const hourCad = hourCadencePhrase(ir);
|
|
362
|
+
return hourCad === null ? minuteHourClause(ir) + "\uFF0C\u5728" + hourList(ir) + tail : hourCad + "\uFF0C" + minuteHourClause(ir) + tail;
|
|
363
|
+
}
|
|
364
|
+
if (compact.minute > 0) {
|
|
332
365
|
return minuteHourClause(ir) + "\uFF0C\u5728" + hourList(ir) + tail;
|
|
333
366
|
}
|
|
334
367
|
return hourList(ir) + tail;
|
|
@@ -347,54 +380,71 @@ function renderHourRange(ir, plan) {
|
|
|
347
380
|
}
|
|
348
381
|
function renderHourStep(ir) {
|
|
349
382
|
const segment = stepSegment(ir, "hour");
|
|
350
|
-
if (segment.startToken !== "*") {
|
|
351
|
-
return hourList(ir);
|
|
352
|
-
}
|
|
353
383
|
if (segment.fires.length <= 2) {
|
|
354
384
|
return joinAnd(segment.fires.map(hourWord));
|
|
355
385
|
}
|
|
356
|
-
return
|
|
386
|
+
return hourCadencePhrase(ir);
|
|
357
387
|
}
|
|
358
388
|
function hourStride(ir) {
|
|
359
389
|
const segments = fieldSegments(ir, "hour");
|
|
360
390
|
if (segments.length === 1 && segments[0].kind === "step") {
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
if (start !== 0 || 24 % segment.interval !== 0) {
|
|
364
|
-
return null;
|
|
365
|
-
}
|
|
366
|
-
return {
|
|
367
|
-
interval: segment.interval,
|
|
368
|
-
last: segment.fires[segment.fires.length - 1]
|
|
369
|
-
};
|
|
391
|
+
const { fires, interval } = segments[0];
|
|
392
|
+
return { interval, start: fires[0], last: fires[fires.length - 1] };
|
|
370
393
|
}
|
|
371
394
|
const values = singleValues(segments);
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
395
|
+
return values && arithmeticStep(values);
|
|
396
|
+
}
|
|
397
|
+
function hourCadencePhrase(ir) {
|
|
398
|
+
const stride = hourStride(ir);
|
|
399
|
+
return stride && renderStride({
|
|
400
|
+
...stride,
|
|
401
|
+
cycle: 24,
|
|
402
|
+
unit: UNITS.hour,
|
|
403
|
+
mark: "\u70B9",
|
|
404
|
+
anchor: ""
|
|
405
|
+
});
|
|
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);
|
|
375
413
|
}
|
|
376
|
-
return
|
|
414
|
+
return null;
|
|
377
415
|
}
|
|
378
416
|
function hourCadence(ir) {
|
|
379
417
|
const stride = hourStride(ir);
|
|
380
418
|
if (!stride) {
|
|
381
419
|
return null;
|
|
382
420
|
}
|
|
383
|
-
const fires = stride.last / stride.interval + 1;
|
|
421
|
+
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
384
422
|
if (ir.pattern.second === "0" && fires <= maxClockTimes) {
|
|
385
423
|
return null;
|
|
386
424
|
}
|
|
387
|
-
const prefix =
|
|
425
|
+
const prefix = hourCadencePhrase(ir);
|
|
426
|
+
if (prefix.indexOf("\u81F3") !== -1) {
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
388
429
|
const minute = +ir.pattern.minute;
|
|
389
430
|
const subMinute = ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
390
431
|
if (minute === 0 && subMinute) {
|
|
391
|
-
return
|
|
432
|
+
return minuteZeroConfinement(ir, stride, prefix);
|
|
392
433
|
}
|
|
393
434
|
if (minute === 0) {
|
|
394
435
|
return prefix + "0\u5206" + secondTail(ir);
|
|
395
436
|
}
|
|
396
437
|
return ir.pattern.second === "0" ? prefix + minute + "\u5206" : prefix + minute + "\u5206" + secondTail(ir);
|
|
397
438
|
}
|
|
439
|
+
function hourCadenceText(ir) {
|
|
440
|
+
if (ir.shapes.minute !== "single") {
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
if (+ir.pattern.minute === 0 && ir.pattern.second === "0") {
|
|
444
|
+
return hourCadencePhrase(ir);
|
|
445
|
+
}
|
|
446
|
+
return hourCadence(ir);
|
|
447
|
+
}
|
|
398
448
|
function secondTail(ir) {
|
|
399
449
|
const sec = secondClause(ir);
|
|
400
450
|
return sec === "\u6BCF\u79D2" ? "\u7684\u6BCF\u4E00\u79D2" : "\u7684" + sec;
|
|
@@ -442,8 +492,8 @@ function minuteClause(ir) {
|
|
|
442
492
|
}
|
|
443
493
|
return valueList(fieldSegments(ir, "minute"), "\u5206");
|
|
444
494
|
}
|
|
445
|
-
function
|
|
446
|
-
return
|
|
495
|
+
function clockRestCarriesSecond(rest) {
|
|
496
|
+
return rest.kind === "clockTimes" && rest.times.some((time) => Boolean(time.second));
|
|
447
497
|
}
|
|
448
498
|
function composeSecondsOnHour(ir, plan, opts) {
|
|
449
499
|
const sec = secondClause(ir);
|
|
@@ -459,17 +509,19 @@ function composeSecondsOnHour(ir, plan, opts) {
|
|
|
459
509
|
return composeMinuteZeroClocks(ir, sec);
|
|
460
510
|
}
|
|
461
511
|
const restText = render(ir, rest, opts);
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
}
|
|
512
|
+
const secTail = clockRestCarriesSecond(rest) ? "" : sec;
|
|
513
|
+
if (composedClock && isDaily(ir)) {
|
|
514
|
+
return "\u6BCF\u5929" + restText + secTail;
|
|
466
515
|
}
|
|
467
516
|
if (rest.kind === "singleMinute") {
|
|
468
517
|
return restText + "\uFF0C" + sec;
|
|
469
518
|
}
|
|
470
|
-
return restText +
|
|
519
|
+
return restText + secTail;
|
|
471
520
|
}
|
|
472
521
|
function composeMinuteZeroClocks(ir, sec) {
|
|
522
|
+
if (hasHourWindow(ir)) {
|
|
523
|
+
return isDaily(ir) ? "\u6BCF\u5929" + hourRangeWindow(ir, sec) : hourRangeWindow(ir, sec);
|
|
524
|
+
}
|
|
473
525
|
const clocks = hourFires(ir).map(function clock(hour) {
|
|
474
526
|
return hour === 12 ? "\u6B63\u5348" : hourWord(hour) + "0\u5206";
|
|
475
527
|
});
|
|
@@ -478,11 +530,24 @@ function composeMinuteZeroClocks(ir, sec) {
|
|
|
478
530
|
const core = joinAnd(clocks) + tail;
|
|
479
531
|
return isDaily(ir) ? "\u6BCF\u5929" + core : core;
|
|
480
532
|
}
|
|
533
|
+
function hasHourWindow(ir) {
|
|
534
|
+
return fieldSegments(ir, "hour").some(function range(segment) {
|
|
535
|
+
return segment.kind === "range";
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
function hourRangeWindow(ir, sec) {
|
|
539
|
+
const span = hourList(ir);
|
|
540
|
+
if (ir.pattern.second === "*" || ir.shapes.second === "step") {
|
|
541
|
+
return span + "0\u5206" + (sec === "\u6BCF\u79D2" ? "\u7684\u6BCF\u4E00\u79D2" : "\u7684" + sec);
|
|
542
|
+
}
|
|
543
|
+
return span + "\uFF0C" + sec;
|
|
544
|
+
}
|
|
481
545
|
function composeSecondsCadence(ir) {
|
|
482
546
|
const sec = secondClause(ir);
|
|
483
547
|
const tail = minuteClause(ir) + sec;
|
|
484
|
-
|
|
485
|
-
|
|
548
|
+
const hourCad = hourCadencePhrase(ir);
|
|
549
|
+
if (hourCad !== null) {
|
|
550
|
+
return hourCad + (hourCad.indexOf("\u81F3") === -1 ? "\u7684" : "\uFF0C") + tail;
|
|
486
551
|
}
|
|
487
552
|
if (ir.shapes.hour === "single") {
|
|
488
553
|
return hourWord(hourFires(ir)[0]) + "\u7684" + tail;
|
|
@@ -509,8 +574,9 @@ function composeSecondsListed(ir) {
|
|
|
509
574
|
if (ir.shapes.hour === "wildcard") {
|
|
510
575
|
return minutes + "\uFF0C" + sec;
|
|
511
576
|
}
|
|
512
|
-
|
|
513
|
-
|
|
577
|
+
const hourCad = hourCadencePhrase(ir);
|
|
578
|
+
if (hourCad !== null) {
|
|
579
|
+
return hourCad + "\uFF0C" + minutes + "\uFF0C" + sec;
|
|
514
580
|
}
|
|
515
581
|
return hourFrame(ir) + minutes + "\uFF0C" + sec;
|
|
516
582
|
}
|
|
@@ -597,7 +663,7 @@ function quartzDate(token, monthPrefix) {
|
|
|
597
663
|
if (token.startsWith("L-")) {
|
|
598
664
|
return monthPrefix + "\u6700\u540E\u7B2C" + token.slice(2) + "\u5929";
|
|
599
665
|
}
|
|
600
|
-
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";
|
|
601
667
|
}
|
|
602
668
|
function datePhrase(ir) {
|
|
603
669
|
const month = monthPhrase(ir);
|
|
@@ -611,7 +677,11 @@ function datePhrase(ir) {
|
|
|
611
677
|
if (ir.shapes.date === "step") {
|
|
612
678
|
return month + cadence(stepSegment(ir, "date").interval, "\u5929");
|
|
613
679
|
}
|
|
614
|
-
|
|
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);
|
|
615
685
|
}
|
|
616
686
|
function dateCore(ir, quartzPrefix) {
|
|
617
687
|
if (ir.shapes.date === "quartz") {
|
|
@@ -653,10 +723,8 @@ function weekdayPhrase(ir, orContext, monthPrefix) {
|
|
|
653
723
|
return "\u6BCF" + weekdayName(from) + "\u81F3" + weekdayName(to);
|
|
654
724
|
}
|
|
655
725
|
const days = [];
|
|
656
|
-
segs.forEach(function expand(seg) {
|
|
657
|
-
if (seg.kind === "
|
|
658
|
-
days.push(...seg.fires);
|
|
659
|
-
} else if (seg.kind === "single") {
|
|
726
|
+
orderWeekdaysForDisplay(segs).forEach(function expand(seg) {
|
|
727
|
+
if (seg.kind === "single") {
|
|
660
728
|
days.push(toFieldNumber(seg.value, weekdayNumbers));
|
|
661
729
|
}
|
|
662
730
|
});
|
|
@@ -722,7 +790,7 @@ function composeWindow(ir, core) {
|
|
|
722
790
|
return qualifier(ir) + core;
|
|
723
791
|
}
|
|
724
792
|
function hourCadenceApplies(ir) {
|
|
725
|
-
return
|
|
793
|
+
return hourCadenceText(ir) !== null;
|
|
726
794
|
}
|
|
727
795
|
function describe(ir, opts) {
|
|
728
796
|
const { kind } = ir.plan;
|
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
|
}
|
|
@@ -223,8 +243,18 @@ function minuteHourClause(ir) {
|
|
|
223
243
|
function renderMinutePast(ir) {
|
|
224
244
|
return minuteHourClause(ir);
|
|
225
245
|
}
|
|
246
|
+
function hourSegmentWords(segment) {
|
|
247
|
+
if (segment.kind === "range") {
|
|
248
|
+
return [hourWord(+segment.bounds[0]) + "\u81F3" + hourWord(+segment.bounds[1])];
|
|
249
|
+
}
|
|
250
|
+
if (segment.kind === "step") {
|
|
251
|
+
return segment.fires.map(hourWord);
|
|
252
|
+
}
|
|
253
|
+
return [hourWord(+segment.value)];
|
|
254
|
+
}
|
|
226
255
|
function hourList(ir) {
|
|
227
|
-
|
|
256
|
+
const words = fieldSegments(ir, "hour").flatMap(hourSegmentWords);
|
|
257
|
+
return joinAnd(words);
|
|
228
258
|
}
|
|
229
259
|
function hourFrame(ir) {
|
|
230
260
|
if (ir.shapes.hour === "range") {
|
|
@@ -237,9 +267,11 @@ function renderMinuteFrequency(ir, plan) {
|
|
|
237
267
|
const minuteStep = stepSegment(ir, "minute");
|
|
238
268
|
const base = stepClause(minuteStep, UNITS.minute, "\u5206", "\u6BCF\u5C0F\u65F6");
|
|
239
269
|
const { hours } = plan;
|
|
240
|
-
if (hours.kind === "step") {
|
|
241
|
-
const
|
|
242
|
-
|
|
270
|
+
if (hours.kind === "step" || hours.kind === "during") {
|
|
271
|
+
const hourCad = hourCadencePhrase(ir);
|
|
272
|
+
if (hourCad !== null) {
|
|
273
|
+
return hourCad + (hourCad.indexOf("\u81F3") === -1 ? "" : "\uFF0C") + base;
|
|
274
|
+
}
|
|
243
275
|
}
|
|
244
276
|
if (hours.kind === "single" || hours.kind === "window" && hours.from === hours.to) {
|
|
245
277
|
return "\u5728" + hourWord(hours.from) + "\u81F3" + hours.from + "\u70B9" + hours.last + "\u5206\u4E4B\u95F4\uFF0C" + base;
|
|
@@ -261,20 +293,21 @@ function renderMinuteSpanInHour(ir, plan) {
|
|
|
261
293
|
}
|
|
262
294
|
function renderMinutesAcrossHours(ir, plan) {
|
|
263
295
|
const { form } = plan;
|
|
296
|
+
const hourCad = hourCadencePhrase(ir);
|
|
264
297
|
if (form === "wildcard") {
|
|
265
|
-
return "\u5728" + hourList(ir) + "\uFF0C\u6BCF\u5206\u949F";
|
|
298
|
+
return hourCad === null ? "\u5728" + hourList(ir) + "\uFF0C\u6BCF\u5206\u949F" : hourCad + "\uFF0C\u6BCF\u5206\u949F";
|
|
266
299
|
}
|
|
267
|
-
return hourList(ir) + "\uFF0C" + minuteHourClause(ir) + "\uFF0C\u6BCF\u5206\u949F";
|
|
300
|
+
return (hourCad ?? hourList(ir)) + "\uFF0C" + minuteHourClause(ir) + "\uFF0C\u6BCF\u5206\u949F";
|
|
268
301
|
}
|
|
269
302
|
function renderMinuteSpanAcrossHourStep(ir, plan) {
|
|
270
303
|
const hourStep = stepSegment(ir, "hour");
|
|
271
304
|
const { form } = plan;
|
|
272
305
|
if (form === "list") {
|
|
273
|
-
return
|
|
306
|
+
return hourCadencePhrase(ir) + "\uFF0C" + renderMinutePast(ir);
|
|
274
307
|
}
|
|
275
308
|
const minuteTail = form === "wildcard" ? "\u6BCF\u5206\u949F" : minuteHourClause(ir) + "\uFF0C\u6BCF\u5206\u949F";
|
|
276
309
|
if (hourStep.startToken !== "*") {
|
|
277
|
-
return
|
|
310
|
+
return hourCadencePhrase(ir) + "\uFF0C" + minuteTail;
|
|
278
311
|
}
|
|
279
312
|
if (hourStep.interval === 2 && form === "wildcard") {
|
|
280
313
|
return "\u5728\u5076\u6570\u5C0F\u65F6\uFF0C" + minuteTail;
|
|
@@ -283,26 +316,26 @@ function renderMinuteSpanAcrossHourStep(ir, plan) {
|
|
|
283
316
|
return form === "wildcard" ? cad + "\u5185\uFF0C" + minuteTail : cad + "\uFF0C" + minuteTail;
|
|
284
317
|
}
|
|
285
318
|
function renderClockTimes(ir, plan, opts) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return cad;
|
|
290
|
-
}
|
|
319
|
+
const cad = hourCadenceText(ir);
|
|
320
|
+
if (cad !== null) {
|
|
321
|
+
return cad;
|
|
291
322
|
}
|
|
292
323
|
const { times } = plan;
|
|
293
324
|
return joinAnd(times.map((t) => clockTime(t.hour, t.minute, t.second, opts)));
|
|
294
325
|
}
|
|
295
326
|
function renderCompactClockTimes(ir, plan) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return cad;
|
|
300
|
-
}
|
|
327
|
+
const cad = hourCadenceText(ir);
|
|
328
|
+
if (cad !== null) {
|
|
329
|
+
return cad;
|
|
301
330
|
}
|
|
302
|
-
const
|
|
331
|
+
const compact = plan;
|
|
303
332
|
const secs = fieldSegments(ir, "second");
|
|
304
333
|
const tail = secs.length && ir.pattern.second !== "0" ? "\uFF0C\u7B2C" + valueText(secs) + "\u79D2" : "";
|
|
305
|
-
if (
|
|
334
|
+
if (!compact.fold) {
|
|
335
|
+
const hourCad = hourCadencePhrase(ir);
|
|
336
|
+
return hourCad === null ? minuteHourClause(ir) + "\uFF0C\u5728" + hourList(ir) + tail : hourCad + "\uFF0C" + minuteHourClause(ir) + tail;
|
|
337
|
+
}
|
|
338
|
+
if (compact.minute > 0) {
|
|
306
339
|
return minuteHourClause(ir) + "\uFF0C\u5728" + hourList(ir) + tail;
|
|
307
340
|
}
|
|
308
341
|
return hourList(ir) + tail;
|
|
@@ -321,54 +354,71 @@ function renderHourRange(ir, plan) {
|
|
|
321
354
|
}
|
|
322
355
|
function renderHourStep(ir) {
|
|
323
356
|
const segment = stepSegment(ir, "hour");
|
|
324
|
-
if (segment.startToken !== "*") {
|
|
325
|
-
return hourList(ir);
|
|
326
|
-
}
|
|
327
357
|
if (segment.fires.length <= 2) {
|
|
328
358
|
return joinAnd(segment.fires.map(hourWord));
|
|
329
359
|
}
|
|
330
|
-
return
|
|
360
|
+
return hourCadencePhrase(ir);
|
|
331
361
|
}
|
|
332
362
|
function hourStride(ir) {
|
|
333
363
|
const segments = fieldSegments(ir, "hour");
|
|
334
364
|
if (segments.length === 1 && segments[0].kind === "step") {
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
if (start !== 0 || 24 % segment.interval !== 0) {
|
|
338
|
-
return null;
|
|
339
|
-
}
|
|
340
|
-
return {
|
|
341
|
-
interval: segment.interval,
|
|
342
|
-
last: segment.fires[segment.fires.length - 1]
|
|
343
|
-
};
|
|
365
|
+
const { fires, interval } = segments[0];
|
|
366
|
+
return { interval, start: fires[0], last: fires[fires.length - 1] };
|
|
344
367
|
}
|
|
345
368
|
const values = singleValues(segments);
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
369
|
+
return values && arithmeticStep(values);
|
|
370
|
+
}
|
|
371
|
+
function hourCadencePhrase(ir) {
|
|
372
|
+
const stride = hourStride(ir);
|
|
373
|
+
return stride && renderStride({
|
|
374
|
+
...stride,
|
|
375
|
+
cycle: 24,
|
|
376
|
+
unit: UNITS.hour,
|
|
377
|
+
mark: "\u70B9",
|
|
378
|
+
anchor: ""
|
|
379
|
+
});
|
|
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);
|
|
349
387
|
}
|
|
350
|
-
return
|
|
388
|
+
return null;
|
|
351
389
|
}
|
|
352
390
|
function hourCadence(ir) {
|
|
353
391
|
const stride = hourStride(ir);
|
|
354
392
|
if (!stride) {
|
|
355
393
|
return null;
|
|
356
394
|
}
|
|
357
|
-
const fires = stride.last / stride.interval + 1;
|
|
395
|
+
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
358
396
|
if (ir.pattern.second === "0" && fires <= maxClockTimes) {
|
|
359
397
|
return null;
|
|
360
398
|
}
|
|
361
|
-
const prefix =
|
|
399
|
+
const prefix = hourCadencePhrase(ir);
|
|
400
|
+
if (prefix.indexOf("\u81F3") !== -1) {
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
362
403
|
const minute = +ir.pattern.minute;
|
|
363
404
|
const subMinute = ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
364
405
|
if (minute === 0 && subMinute) {
|
|
365
|
-
return
|
|
406
|
+
return minuteZeroConfinement(ir, stride, prefix);
|
|
366
407
|
}
|
|
367
408
|
if (minute === 0) {
|
|
368
409
|
return prefix + "0\u5206" + secondTail(ir);
|
|
369
410
|
}
|
|
370
411
|
return ir.pattern.second === "0" ? prefix + minute + "\u5206" : prefix + minute + "\u5206" + secondTail(ir);
|
|
371
412
|
}
|
|
413
|
+
function hourCadenceText(ir) {
|
|
414
|
+
if (ir.shapes.minute !== "single") {
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
if (+ir.pattern.minute === 0 && ir.pattern.second === "0") {
|
|
418
|
+
return hourCadencePhrase(ir);
|
|
419
|
+
}
|
|
420
|
+
return hourCadence(ir);
|
|
421
|
+
}
|
|
372
422
|
function secondTail(ir) {
|
|
373
423
|
const sec = secondClause(ir);
|
|
374
424
|
return sec === "\u6BCF\u79D2" ? "\u7684\u6BCF\u4E00\u79D2" : "\u7684" + sec;
|
|
@@ -416,8 +466,8 @@ function minuteClause(ir) {
|
|
|
416
466
|
}
|
|
417
467
|
return valueList(fieldSegments(ir, "minute"), "\u5206");
|
|
418
468
|
}
|
|
419
|
-
function
|
|
420
|
-
return
|
|
469
|
+
function clockRestCarriesSecond(rest) {
|
|
470
|
+
return rest.kind === "clockTimes" && rest.times.some((time) => Boolean(time.second));
|
|
421
471
|
}
|
|
422
472
|
function composeSecondsOnHour(ir, plan, opts) {
|
|
423
473
|
const sec = secondClause(ir);
|
|
@@ -433,17 +483,19 @@ function composeSecondsOnHour(ir, plan, opts) {
|
|
|
433
483
|
return composeMinuteZeroClocks(ir, sec);
|
|
434
484
|
}
|
|
435
485
|
const restText = render(ir, rest, opts);
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
486
|
+
const secTail = clockRestCarriesSecond(rest) ? "" : sec;
|
|
487
|
+
if (composedClock && isDaily(ir)) {
|
|
488
|
+
return "\u6BCF\u5929" + restText + secTail;
|
|
440
489
|
}
|
|
441
490
|
if (rest.kind === "singleMinute") {
|
|
442
491
|
return restText + "\uFF0C" + sec;
|
|
443
492
|
}
|
|
444
|
-
return restText +
|
|
493
|
+
return restText + secTail;
|
|
445
494
|
}
|
|
446
495
|
function composeMinuteZeroClocks(ir, sec) {
|
|
496
|
+
if (hasHourWindow(ir)) {
|
|
497
|
+
return isDaily(ir) ? "\u6BCF\u5929" + hourRangeWindow(ir, sec) : hourRangeWindow(ir, sec);
|
|
498
|
+
}
|
|
447
499
|
const clocks = hourFires(ir).map(function clock(hour) {
|
|
448
500
|
return hour === 12 ? "\u6B63\u5348" : hourWord(hour) + "0\u5206";
|
|
449
501
|
});
|
|
@@ -452,11 +504,24 @@ function composeMinuteZeroClocks(ir, sec) {
|
|
|
452
504
|
const core = joinAnd(clocks) + tail;
|
|
453
505
|
return isDaily(ir) ? "\u6BCF\u5929" + core : core;
|
|
454
506
|
}
|
|
507
|
+
function hasHourWindow(ir) {
|
|
508
|
+
return fieldSegments(ir, "hour").some(function range(segment) {
|
|
509
|
+
return segment.kind === "range";
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
function hourRangeWindow(ir, sec) {
|
|
513
|
+
const span = hourList(ir);
|
|
514
|
+
if (ir.pattern.second === "*" || ir.shapes.second === "step") {
|
|
515
|
+
return span + "0\u5206" + (sec === "\u6BCF\u79D2" ? "\u7684\u6BCF\u4E00\u79D2" : "\u7684" + sec);
|
|
516
|
+
}
|
|
517
|
+
return span + "\uFF0C" + sec;
|
|
518
|
+
}
|
|
455
519
|
function composeSecondsCadence(ir) {
|
|
456
520
|
const sec = secondClause(ir);
|
|
457
521
|
const tail = minuteClause(ir) + sec;
|
|
458
|
-
|
|
459
|
-
|
|
522
|
+
const hourCad = hourCadencePhrase(ir);
|
|
523
|
+
if (hourCad !== null) {
|
|
524
|
+
return hourCad + (hourCad.indexOf("\u81F3") === -1 ? "\u7684" : "\uFF0C") + tail;
|
|
460
525
|
}
|
|
461
526
|
if (ir.shapes.hour === "single") {
|
|
462
527
|
return hourWord(hourFires(ir)[0]) + "\u7684" + tail;
|
|
@@ -483,8 +548,9 @@ function composeSecondsListed(ir) {
|
|
|
483
548
|
if (ir.shapes.hour === "wildcard") {
|
|
484
549
|
return minutes + "\uFF0C" + sec;
|
|
485
550
|
}
|
|
486
|
-
|
|
487
|
-
|
|
551
|
+
const hourCad = hourCadencePhrase(ir);
|
|
552
|
+
if (hourCad !== null) {
|
|
553
|
+
return hourCad + "\uFF0C" + minutes + "\uFF0C" + sec;
|
|
488
554
|
}
|
|
489
555
|
return hourFrame(ir) + minutes + "\uFF0C" + sec;
|
|
490
556
|
}
|
|
@@ -571,7 +637,7 @@ function quartzDate(token, monthPrefix) {
|
|
|
571
637
|
if (token.startsWith("L-")) {
|
|
572
638
|
return monthPrefix + "\u6700\u540E\u7B2C" + token.slice(2) + "\u5929";
|
|
573
639
|
}
|
|
574
|
-
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";
|
|
575
641
|
}
|
|
576
642
|
function datePhrase(ir) {
|
|
577
643
|
const month = monthPhrase(ir);
|
|
@@ -585,7 +651,11 @@ function datePhrase(ir) {
|
|
|
585
651
|
if (ir.shapes.date === "step") {
|
|
586
652
|
return month + cadence(stepSegment(ir, "date").interval, "\u5929");
|
|
587
653
|
}
|
|
588
|
-
|
|
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);
|
|
589
659
|
}
|
|
590
660
|
function dateCore(ir, quartzPrefix) {
|
|
591
661
|
if (ir.shapes.date === "quartz") {
|
|
@@ -627,10 +697,8 @@ function weekdayPhrase(ir, orContext, monthPrefix) {
|
|
|
627
697
|
return "\u6BCF" + weekdayName(from) + "\u81F3" + weekdayName(to);
|
|
628
698
|
}
|
|
629
699
|
const days = [];
|
|
630
|
-
segs.forEach(function expand(seg) {
|
|
631
|
-
if (seg.kind === "
|
|
632
|
-
days.push(...seg.fires);
|
|
633
|
-
} else if (seg.kind === "single") {
|
|
700
|
+
orderWeekdaysForDisplay(segs).forEach(function expand(seg) {
|
|
701
|
+
if (seg.kind === "single") {
|
|
634
702
|
days.push(toFieldNumber(seg.value, weekdayNumbers));
|
|
635
703
|
}
|
|
636
704
|
});
|
|
@@ -696,7 +764,7 @@ function composeWindow(ir, core) {
|
|
|
696
764
|
return qualifier(ir) + core;
|
|
697
765
|
}
|
|
698
766
|
function hourCadenceApplies(ir) {
|
|
699
|
-
return
|
|
767
|
+
return hourCadenceText(ir) !== null;
|
|
700
768
|
}
|
|
701
769
|
function describe(ir, opts) {
|
|
702
770
|
const { kind } = ir.plan;
|