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/dist/lang/de.js CHANGED
@@ -36,6 +36,26 @@ function arithmeticStep(values) {
36
36
  }
37
37
  return { start: values[0], interval, last: values[values.length - 1] };
38
38
  }
39
+ function weekdayDisplayKey(value) {
40
+ return value === 0 ? 7 : value;
41
+ }
42
+ function orderWeekdaysForDisplay(segments) {
43
+ const flattened = segments.flatMap(function flat(segment) {
44
+ return segment.kind === "step" ? segment.fires.map(function single(value) {
45
+ return { kind: "single", value: "" + value };
46
+ }) : [segment];
47
+ });
48
+ function key(segment) {
49
+ return segment.kind === "range" ? weekdayDisplayKey(+segment.bounds[0]) : weekdayDisplayKey(+segment.value);
50
+ }
51
+ return flattened.map(function index(segment, position) {
52
+ return [segment, position];
53
+ }).sort(function byDisplayKey(a, b) {
54
+ return key(a[0]) - key(b[0]) || a[1] - b[1];
55
+ }).map(function unwrap(pair) {
56
+ return pair[0];
57
+ });
58
+ }
39
59
  function toFieldNumber(token, numberMap) {
40
60
  return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
41
61
  }
@@ -96,6 +116,9 @@ function everyUnit(unit) {
96
116
  function everyN(interval, unit) {
97
117
  return "alle " + interval + " " + unit.plural;
98
118
  }
119
+ function withAnchor(clause, anchor) {
120
+ return anchor ? clause + " " + anchor : clause;
121
+ }
99
122
  function stepSegment(segments) {
100
123
  return segments[0];
101
124
  }
@@ -119,7 +142,10 @@ function stepClause(segment, unit, anchor) {
119
142
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
120
143
  const short = start !== 0 && segment.fires.length <= 3;
121
144
  if (segment.startToken.indexOf("-") !== -1 || short) {
122
- return "in den " + unit.plural + " " + joinList(segment.fires.map(String)) + " " + anchor;
145
+ return withAnchor(
146
+ "in den " + unit.plural + " " + joinList(segment.fires.map(String)),
147
+ anchor
148
+ );
123
149
  }
124
150
  return renderStride({
125
151
  interval: segment.interval,
@@ -180,7 +206,7 @@ function weekdayRange(bounds) {
180
206
  return weekdayName(bounds[0]) + " bis " + weekdayName(bounds[1]);
181
207
  }
182
208
  function weekdayQualifier(ir) {
183
- const segments = flattenSteps(fieldSegments(ir, "weekday"));
209
+ const segments = orderWeekdaysForDisplay(fieldSegments(ir, "weekday"));
184
210
  if (segments.length === 1 && segments[0].kind === "range") {
185
211
  return weekdayRange(segments[0].bounds);
186
212
  }
@@ -320,8 +346,11 @@ function countedPhrase(ir, field, singular, plural) {
320
346
  }
321
347
  return "in den " + plural + " " + joinList(fieldValues(ir, field));
322
348
  }
349
+ function minuteAnchor(ir) {
350
+ return ir.pattern.minute === "*" ? "jeder Minute" : "";
351
+ }
323
352
  function secondsLead(ir) {
324
- return secondsClause(ir, "jeder Minute");
353
+ return secondsClause(ir, minuteAnchor(ir));
325
354
  }
326
355
  function secondsClause(ir, anchor) {
327
356
  if (ir.pattern.second === "*") {
@@ -331,7 +360,7 @@ function secondsClause(ir, anchor) {
331
360
  if (ir.shapes.second === "step") {
332
361
  return stepClause(stepSegment(segments), UNITS.second, anchor);
333
362
  }
334
- return strideFromSegments(segments, UNITS.second, anchor) ?? countedPhrase(ir, "second", "Sekunde", "Sekunden") + " " + anchor;
363
+ return strideFromSegments(segments, UNITS.second, anchor) ?? withAnchor(countedPhrase(ir, "second", "Sekunde", "Sekunden"), anchor);
335
364
  }
336
365
  function spanTime(hour, minute, sep) {
337
366
  return hour + sep + pad(minute);
@@ -432,9 +461,17 @@ function renderMinuteSpanInHour(ir, plan, opts) {
432
461
  const sep = opts.style.sep;
433
462
  return "jede Minute von " + spanTime(plan.hour, plan.span[0], sep) + " bis " + spanTime(plan.hour, plan.span[1], sep) + " Uhr";
434
463
  }
464
+ function isEveryOtherMinuteSeconds(ir, plan) {
465
+ if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
466
+ return false;
467
+ }
468
+ const minuteStep = stepSegment(ir.analyses.segments.minute);
469
+ return minuteStep.startToken === "*" && minuteStep.interval === 2;
470
+ }
435
471
  function renderComposeSeconds(ir, plan, opts) {
436
472
  if ((plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes") && ir.shapes.minute === "single") {
437
- const cadence = hourCadence(ir, +ir.pattern.minute);
473
+ const minute = +ir.pattern.minute;
474
+ const cadence = hourCadence(ir, minute) ?? hourRangeCadence(ir, minute);
438
475
  if (cadence !== null) {
439
476
  return cadence;
440
477
  }
@@ -442,13 +479,12 @@ function renderComposeSeconds(ir, plan, opts) {
442
479
  if (composeMinuteZero(ir, plan)) {
443
480
  return secondsLead(ir) + " " + clockMinuteGenitive(plan.rest.times, opts.style.sep);
444
481
  }
445
- if (plan.rest.kind === "minuteFrequency" && ir.shapes.second === "wildcard" && ir.shapes.hour === "wildcard") {
446
- const minuteStep = stepSegment(ir.analyses.segments.minute);
447
- if (minuteStep.startToken === "*" && minuteStep.interval === 2) {
448
- return secondsLead(ir) + " jeder zweiten Minute";
449
- }
482
+ if (isEveryOtherMinuteSeconds(ir, plan)) {
483
+ return secondsLead(ir) + " jeder zweiten Minute";
450
484
  }
451
- return secondsLead(ir) + ", " + render(ir, plan.rest, opts);
485
+ const restOwnsLead = plan.rest.kind === "compactClockTimes" && ir.analyses.clockSecond;
486
+ const lead = restOwnsLead ? "" : secondsLead(ir) + ", ";
487
+ return lead + render(ir, plan.rest, opts);
452
488
  }
453
489
  function composeMinuteZero(ir, plan) {
454
490
  return plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0);
@@ -461,31 +497,37 @@ function clockMinuteGenitive(times, sep) {
461
497
  }
462
498
  function renderMinutesAcrossHours(ir, plan, opts) {
463
499
  const sep = opts.style.sep;
500
+ const cadence = unevenHourCadence(ir);
464
501
  if (plan.form === "wildcard") {
465
- return "jede Minute " + duringHours(ir, plan.times, sep);
502
+ return cadence ? "jede Minute, " + cadence : "jede Minute " + duringHours(ir, plan.times, sep);
503
+ }
504
+ const minuteLead = strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten");
505
+ if (cadence !== null) {
506
+ return minuteLead + ", " + cadence;
466
507
  }
467
508
  const hours = plan.times.kind === "fires" ? atHours(plan.times.fires) : joinList(hourSegmentParts(ir, 0, 0, sep));
468
- return (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
509
+ return minuteLead + ", " + hours;
469
510
  }
470
511
  function renderMinuteSpanAcrossHourStep(ir, plan) {
512
+ const cadence = unevenHourCadence(ir);
471
513
  if (plan.form === "wildcard") {
472
514
  return "jede Minute " + everyNthHour(stepSegment(ir.analyses.segments.hour));
473
515
  }
474
516
  const segment = stepSegment(ir.analyses.segments.hour);
475
- const hours = confinedHourStride(segment) ? everyNthHour(segment) : atHours(segment.fires);
517
+ const hours = cadence ?? (confinedHourStride(segment) ? everyNthHour(segment) : atHours(segment.fires));
476
518
  return (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
477
519
  }
478
520
  function renderCompactClockTimes(ir, plan, opts) {
479
521
  const sep = opts.style.sep;
480
522
  if (plan.fold) {
481
- const cadence = hourCadence(ir, plan.minute);
523
+ const cadence = hourCadence(ir, plan.minute) ?? hourRangeCadence(ir, plan.minute);
482
524
  if (cadence !== null) {
483
525
  return cadence;
484
526
  }
485
527
  const hourly = fieldSegments(ir, "hour").some((segment) => segment.kind === "range");
486
528
  return (hourly ? "st\xFCndlich " : "t\xE4glich ") + joinList(hourSegmentParts(ir, plan.minute, ir.analyses.clockSecond, sep));
487
529
  }
488
- const hours = fieldSegments(ir, "hour").some((segment) => segment.kind === "range") ? joinList(hourSegmentParts(ir, 0, 0, sep)) : atHours(hourFires(ir));
530
+ const hours = unevenHourCadence(ir) ?? (fieldSegments(ir, "hour").some((segment) => segment.kind === "range") ? joinList(hourSegmentParts(ir, 0, 0, sep)) : atHours(hourFires(ir)));
489
531
  const lead = ir.analyses.clockSecond ? countedPhrase(ir, "second", "Sekunde", "Sekunden") + ", " : "";
490
532
  return lead + (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
491
533
  }
@@ -493,18 +535,25 @@ function renderMinuteFrequency(ir, plan, opts) {
493
535
  const segment = stepSegment(ir.analyses.segments.minute);
494
536
  const sep = opts.style.sep;
495
537
  const clean = cleanStep(segment, 60);
496
- const base = stepClause(segment, UNITS.minute, "jeder Stunde");
497
538
  if (plan.hours.kind === "window") {
539
+ const singleHour = plan.hours.from === plan.hours.to;
540
+ const base2 = stepClause(
541
+ segment,
542
+ UNITS.minute,
543
+ singleHour ? "" : "jeder Stunde"
544
+ );
498
545
  const window = hourWindow(
499
546
  plan.hours.from,
500
547
  plan.hours.to,
501
548
  plan.hours.last,
502
549
  sep
503
550
  );
504
- return clean ? base + " " + window : base + ", " + window;
551
+ return clean ? base2 + " " + window : base2 + ", " + window;
505
552
  }
553
+ const base = stepClause(segment, UNITS.minute, "jeder Stunde");
506
554
  if (plan.hours.kind === "during") {
507
- return base + " " + duringHours(ir, plan.hours.times, sep);
555
+ const cadence = unevenHourCadence(ir);
556
+ return cadence ? base + ", " + cadence : base + " " + duringHours(ir, plan.hours.times, sep);
508
557
  }
509
558
  if (plan.hours.kind === "step") {
510
559
  return base + " " + everyNthHour(stepSegment(ir.analyses.segments.hour));
@@ -512,8 +561,23 @@ function renderMinuteFrequency(ir, plan, opts) {
512
561
  return base;
513
562
  }
514
563
  function hourStepPhrase(ir) {
564
+ const cadence = unevenHourCadence(ir);
565
+ if (cadence !== null) {
566
+ return cadence;
567
+ }
515
568
  const segment = stepSegment(ir.analyses.segments.hour);
516
- return cleanStep(segment, 24) ? everyN(segment.interval, UNITS.hour) : atHours(segment.fires);
569
+ if (cleanStep(segment, 24)) {
570
+ return everyN(segment.interval, UNITS.hour);
571
+ }
572
+ const stride = openOffsetCleanStride(ir, segment);
573
+ return stride ? hourStrideCadence(stride) : atHours(segment.fires);
574
+ }
575
+ function openOffsetCleanStride(ir, segment) {
576
+ if (segment.startToken.indexOf("-") !== -1) {
577
+ return null;
578
+ }
579
+ const stride = hourStride(ir);
580
+ return stride && offsetCleanStride(stride) ? stride : null;
517
581
  }
518
582
  function hourStrideCadence(stride) {
519
583
  const { start, interval, last } = stride;
@@ -527,6 +591,27 @@ function hourStrideCadence(stride) {
527
591
  }
528
592
  return cadence + " von " + start + " bis " + last + " Uhr";
529
593
  }
594
+ function hourListStride(values) {
595
+ if (values.length < 2) {
596
+ return null;
597
+ }
598
+ const interval = values[1] - values[0];
599
+ if (interval < 2) {
600
+ return null;
601
+ }
602
+ for (let i = 2; i < values.length; i += 1) {
603
+ if (values[i] - values[i - 1] !== interval) {
604
+ return null;
605
+ }
606
+ }
607
+ if (values[0] !== 0 && values.length < 5) {
608
+ return null;
609
+ }
610
+ return { interval, last: values[values.length - 1], start: values[0] };
611
+ }
612
+ function offsetCleanStride(stride) {
613
+ return stride.start < stride.interval && 24 % stride.interval === 0;
614
+ }
530
615
  function hourStride(ir) {
531
616
  const segments = fieldSegments(ir, "hour");
532
617
  if (!segments) {
@@ -534,12 +619,21 @@ function hourStride(ir) {
534
619
  }
535
620
  if (segments.length === 1 && segments[0].kind === "step") {
536
621
  const segment = segments[0];
622
+ if (segment.fires.length < 2) {
623
+ return null;
624
+ }
537
625
  const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
538
626
  return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
539
627
  }
540
628
  const values = singleValues(segments);
541
- const step = values && arithmeticStep(values);
542
- return step || null;
629
+ return values && hourListStride(values);
630
+ }
631
+ function unevenHourCadence(ir) {
632
+ const stride = hourStride(ir);
633
+ if (!stride || offsetCleanStride(stride)) {
634
+ return null;
635
+ }
636
+ return hourStrideCadence(stride);
543
637
  }
544
638
  function subMinuteSecond(ir) {
545
639
  return ir.pattern.second === "*" || ir.shapes.second === "step";
@@ -547,7 +641,7 @@ function subMinuteSecond(ir) {
547
641
  function hourCadenceLead(ir, minute) {
548
642
  if (minute === 0) {
549
643
  if (subMinuteSecond(ir)) {
550
- return secondsClause(ir, "jeder Minute") + " f\xFCr eine Minute";
644
+ return withAnchor(secondsClause(ir, minuteAnchor(ir)), "f\xFCr eine Minute");
551
645
  }
552
646
  return secondsClause(ir, "jeder Stunde");
553
647
  }
@@ -555,7 +649,7 @@ function hourCadenceLead(ir, minute) {
555
649
  if (ir.pattern.second === "0") {
556
650
  return minutePhrase;
557
651
  }
558
- return secondsClause(ir, "jeder Minute") + ", " + minutePhrase;
652
+ return secondsClause(ir, minuteAnchor(ir)) + ", " + minutePhrase;
559
653
  }
560
654
  function hourCadence(ir, minute) {
561
655
  const stride = hourStride(ir);
@@ -563,37 +657,60 @@ function hourCadence(ir, minute) {
563
657
  return null;
564
658
  }
565
659
  const fires = (stride.last - stride.start) / stride.interval + 1;
566
- if (ir.pattern.second === "0" && fires <= maxClockTimes) {
660
+ if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
567
661
  return null;
568
662
  }
569
663
  const segment = fieldSegments(ir, "hour")[0];
570
664
  const confined = minute === 0 && subMinuteSecond(ir) && fieldSegments(ir, "hour").length === 1 && segment.kind === "step" && confinedHourStride(segment);
571
665
  if (confined) {
572
- return secondsClause(ir, "jeder Minute") + " f\xFCr eine Minute " + everyNthHour(segment);
666
+ return withAnchor(secondsClause(ir, minuteAnchor(ir)), "f\xFCr eine Minute") + " " + everyNthHour(segment);
667
+ }
668
+ if (minute === 0 && ir.pattern.second === "0") {
669
+ return hourStrideCadence(stride);
573
670
  }
574
671
  return hourCadenceLead(ir, minute) + ", " + hourStrideCadence(stride);
575
672
  }
576
673
  function hourCadenceApplies(ir) {
577
- return ir.shapes.minute === "single" && hourCadence(ir, +ir.pattern.minute) !== null;
674
+ if (ir.shapes.minute !== "single") {
675
+ return false;
676
+ }
677
+ const minute = +ir.pattern.minute;
678
+ return hourCadence(ir, minute) !== null || hourRangeCadence(ir, minute) !== null;
679
+ }
680
+ function hasHourWindow(ir) {
681
+ const segments = fieldSegments(ir, "hour");
682
+ return !!segments && segments.some(function range(segment) {
683
+ return segment.kind === "range";
684
+ });
685
+ }
686
+ function hourRangeCadence(ir, minute) {
687
+ if (minute !== 0 || !hasHourWindow(ir) || ir.pattern.second === "0") {
688
+ return null;
689
+ }
690
+ return hourCadenceLead(ir, minute) + ", " + hourRangeWindowTail(ir);
691
+ }
692
+ function hourRangeWindowTail(ir) {
693
+ return joinList(hourSegmentParts(ir, 0, 0, ":"));
578
694
  }
579
695
  function renderHourRange(ir, plan, opts) {
580
- const window = hourWindow(
581
- plan.from,
582
- plan.to,
583
- plan.boundMinute ?? 0,
584
- opts.style.sep
585
- );
696
+ const last = plan.minuteForm === "wildcard" ? plan.boundMinute ?? 0 : 0;
697
+ const window = hourWindow(plan.from, plan.to, last, opts.style.sep);
586
698
  if (plan.minuteForm === "wildcard") {
587
699
  return "jede Minute " + window;
588
700
  }
589
701
  if (plan.minuteForm === "lead" && ir.pattern.minute === "0") {
590
702
  return "st\xFCndlich " + window;
591
703
  }
592
- return countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde, " + window;
704
+ return (strideFromSegments(
705
+ fieldSegments(ir, "minute"),
706
+ UNITS.minute,
707
+ "jeder Stunde"
708
+ ) ?? countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde") + ", " + window;
593
709
  }
594
710
  function renderClockTimes(ir, plan, opts) {
595
711
  if (ir.shapes.minute === "single") {
596
- const cadence = hourCadence(ir, +ir.pattern.minute);
712
+ const minute = +ir.pattern.minute;
713
+ const cadence = hourCadence(ir, minute) ?? hourRangeCadence(ir, minute);
597
714
  if (cadence !== null) {
598
715
  return cadence;
599
716
  }
@@ -653,7 +770,11 @@ function needsDailyFrame(ir) {
653
770
  if (ir.plan.kind === "clockTimes" || isComposeMinuteZero(ir)) {
654
771
  return true;
655
772
  }
656
- return ir.plan.kind === "hourStep" && !cleanStep(stepSegment(ir.analyses.segments.hour), 24);
773
+ if (ir.plan.kind !== "hourStep") {
774
+ return false;
775
+ }
776
+ const segment = stepSegment(ir.analyses.segments.hour);
777
+ return !cleanStep(segment, 24) && !openOffsetCleanStride(ir, segment);
657
778
  }
658
779
  function render(ir, plan, opts) {
659
780
  return renderers[plan.kind](