cronli5 0.1.4 → 0.1.6

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
@@ -14,12 +14,28 @@ var weekdayNumbers = {
14
14
  FRI: 5,
15
15
  SAT: 6
16
16
  };
17
+ var maxClockTimes = 6;
17
18
 
18
19
  // src/core/util.ts
19
20
  function isNonNegativeInteger(value) {
20
21
  const digits = /^\d+$/;
21
22
  return digits.test(value);
22
23
  }
24
+ function arithmeticStep(values) {
25
+ if (values.length < 5) {
26
+ return null;
27
+ }
28
+ const interval = values[1] - values[0];
29
+ if (interval < 2) {
30
+ return null;
31
+ }
32
+ for (let i = 2; i < values.length; i += 1) {
33
+ if (values[i] - values[i - 1] !== interval) {
34
+ return null;
35
+ }
36
+ }
37
+ return { start: values[0], interval, last: values[values.length - 1] };
38
+ }
23
39
  function toFieldNumber(token, numberMap) {
24
40
  return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
25
41
  }
@@ -86,6 +102,49 @@ function stepSegment(segments) {
86
102
  function cleanStep(segment, cycle) {
87
103
  return (segment.startToken === "*" || +segment.startToken === 0) && cycle % segment.interval === 0;
88
104
  }
105
+ function renderStride(stride) {
106
+ const { interval, start, last, cycle, unit, anchor } = stride;
107
+ const cadence = everyN(interval, unit);
108
+ const tiles = cycle % interval === 0;
109
+ if (start === 0 && tiles) {
110
+ return cadence;
111
+ }
112
+ const tail = anchor ? " " + anchor : "";
113
+ if (start < interval && tiles) {
114
+ return cadence + " ab " + unit.singular + " " + start + tail;
115
+ }
116
+ return cadence + " von " + unit.singular + " " + start + " bis " + last + tail;
117
+ }
118
+ function stepClause(segment, unit, anchor) {
119
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
120
+ const short = start !== 0 && segment.fires.length <= 3;
121
+ if (segment.startToken.indexOf("-") !== -1 || short) {
122
+ return "in den " + unit.plural + " " + joinList(segment.fires.map(String)) + " " + anchor;
123
+ }
124
+ return renderStride({
125
+ interval: segment.interval,
126
+ start,
127
+ last: segment.fires[segment.fires.length - 1],
128
+ cycle: 60,
129
+ unit,
130
+ anchor
131
+ });
132
+ }
133
+ function singleValues(segments) {
134
+ const values = [];
135
+ for (const segment of segments) {
136
+ if (segment.kind !== "single") {
137
+ return null;
138
+ }
139
+ values.push(+segment.value);
140
+ }
141
+ return values;
142
+ }
143
+ function strideFromSegments(segments, unit, anchor) {
144
+ const values = singleValues(segments);
145
+ const step = values && arithmeticStep(values);
146
+ return step ? renderStride({ ...step, cycle: 60, unit, anchor }) : null;
147
+ }
89
148
  var weekdayNames = [
90
149
  "sonntags",
91
150
  "montags",
@@ -152,6 +211,13 @@ function everyNthHour(segment) {
152
211
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
153
212
  return start === 0 ? base : base + " ab " + start + " Uhr";
154
213
  }
214
+ function confinedHourStride(segment) {
215
+ if (segment.startToken.indexOf("-") !== -1) {
216
+ return false;
217
+ }
218
+ const start = segment.startToken === "*" ? 0 : +segment.startToken;
219
+ return 24 % segment.interval === 0 && start < segment.interval;
220
+ }
155
221
  function weekdayNoun(token) {
156
222
  return weekdayNouns[toFieldNumber(token, weekdayNumbers)];
157
223
  }
@@ -255,14 +321,17 @@ function countedPhrase(ir, field, singular, plural) {
255
321
  return "in den " + plural + " " + joinList(fieldValues(ir, field));
256
322
  }
257
323
  function secondsLead(ir) {
324
+ return secondsClause(ir, "jeder Minute");
325
+ }
326
+ function secondsClause(ir, anchor) {
258
327
  if (ir.pattern.second === "*") {
259
328
  return "jede Sekunde";
260
329
  }
261
330
  const segments = ir.analyses.segments.second;
262
- if (ir.shapes.second === "step" && cleanStep(stepSegment(segments), 60)) {
263
- return everyN(stepSegment(segments).interval, UNITS.second);
331
+ if (ir.shapes.second === "step") {
332
+ return stepClause(stepSegment(segments), UNITS.second, anchor);
264
333
  }
265
- return countedPhrase(ir, "second", "Sekunde", "Sekunden") + " jeder Minute";
334
+ return strideFromSegments(segments, UNITS.second, anchor) ?? countedPhrase(ir, "second", "Sekunde", "Sekunden") + " " + anchor;
266
335
  }
267
336
  function spanTime(hour, minute, sep) {
268
337
  return hour + sep + pad(minute);
@@ -331,8 +400,15 @@ function renderEveryHour() {
331
400
  function renderSeconds(ir) {
332
401
  return secondsLead(ir);
333
402
  }
403
+ function minutePastClause(ir) {
404
+ return strideFromSegments(
405
+ fieldSegments(ir, "minute"),
406
+ UNITS.minute,
407
+ "jeder Stunde"
408
+ ) ?? countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
409
+ }
334
410
  function renderMinutePast(ir) {
335
- return countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
411
+ return minutePastClause(ir);
336
412
  }
337
413
  function renderSecondsWithinMinute(ir, plan) {
338
414
  if (plan.singleSecond) {
@@ -356,11 +432,30 @@ function renderMinuteSpanInHour(ir, plan, opts) {
356
432
  const sep = opts.style.sep;
357
433
  return "jede Minute von " + spanTime(plan.hour, plan.span[0], sep) + " bis " + spanTime(plan.hour, plan.span[1], sep) + " Uhr";
358
434
  }
435
+ function isEveryOtherMinuteSeconds(ir, plan) {
436
+ if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
437
+ return false;
438
+ }
439
+ const minuteStep = stepSegment(ir.analyses.segments.minute);
440
+ return minuteStep.startToken === "*" && minuteStep.interval === 2;
441
+ }
359
442
  function renderComposeSeconds(ir, plan, opts) {
443
+ if ((plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes") && ir.shapes.minute === "single") {
444
+ const minute = +ir.pattern.minute;
445
+ const cadence = hourCadence(ir, minute) ?? hourRangeCadence(ir, minute);
446
+ if (cadence !== null) {
447
+ return cadence;
448
+ }
449
+ }
360
450
  if (composeMinuteZero(ir, plan)) {
361
451
  return secondsLead(ir) + " " + clockMinuteGenitive(plan.rest.times, opts.style.sep);
362
452
  }
363
- return secondsLead(ir) + ", " + render(ir, plan.rest, opts);
453
+ if (isEveryOtherMinuteSeconds(ir, plan)) {
454
+ return secondsLead(ir) + " jeder zweiten Minute";
455
+ }
456
+ const restOwnsLead = plan.rest.kind === "compactClockTimes" && ir.analyses.clockSecond;
457
+ const lead = restOwnsLead ? "" : secondsLead(ir) + ", ";
458
+ return lead + render(ir, plan.rest, opts);
364
459
  }
365
460
  function composeMinuteZero(ir, plan) {
366
461
  return plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0);
@@ -373,33 +468,45 @@ function clockMinuteGenitive(times, sep) {
373
468
  }
374
469
  function renderMinutesAcrossHours(ir, plan, opts) {
375
470
  const sep = opts.style.sep;
471
+ const cadence = unevenHourCadence(ir);
376
472
  if (plan.form === "wildcard") {
377
- return "jede Minute " + duringHours(ir, plan.times, sep);
473
+ return cadence ? "jede Minute, " + cadence : "jede Minute " + duringHours(ir, plan.times, sep);
474
+ }
475
+ const minuteLead = strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten");
476
+ if (cadence !== null) {
477
+ return minuteLead + ", " + cadence;
378
478
  }
379
479
  const hours = plan.times.kind === "fires" ? atHours(plan.times.fires) : joinList(hourSegmentParts(ir, 0, 0, sep));
380
- return countedPhrase(ir, "minute", "Minute", "Minuten") + ", " + hours;
480
+ return minuteLead + ", " + hours;
381
481
  }
382
482
  function renderMinuteSpanAcrossHourStep(ir, plan) {
483
+ const cadence = unevenHourCadence(ir);
383
484
  if (plan.form === "wildcard") {
384
485
  return "jede Minute " + everyNthHour(stepSegment(ir.analyses.segments.hour));
385
486
  }
386
- return countedPhrase(ir, "minute", "Minute", "Minuten") + ", " + hourStepPhrase(ir);
487
+ const segment = stepSegment(ir.analyses.segments.hour);
488
+ const hours = cadence ?? (confinedHourStride(segment) ? everyNthHour(segment) : atHours(segment.fires));
489
+ return (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
387
490
  }
388
491
  function renderCompactClockTimes(ir, plan, opts) {
389
492
  const sep = opts.style.sep;
390
493
  if (plan.fold) {
494
+ const cadence = hourCadence(ir, plan.minute) ?? hourRangeCadence(ir, plan.minute);
495
+ if (cadence !== null) {
496
+ return cadence;
497
+ }
391
498
  const hourly = fieldSegments(ir, "hour").some((segment) => segment.kind === "range");
392
499
  return (hourly ? "st\xFCndlich " : "t\xE4glich ") + joinList(hourSegmentParts(ir, plan.minute, ir.analyses.clockSecond, sep));
393
500
  }
394
- const hours = fieldSegments(ir, "hour").some((segment) => segment.kind === "range") ? joinList(hourSegmentParts(ir, 0, 0, sep)) : atHours(hourFires(ir));
501
+ const hours = unevenHourCadence(ir) ?? (fieldSegments(ir, "hour").some((segment) => segment.kind === "range") ? joinList(hourSegmentParts(ir, 0, 0, sep)) : atHours(hourFires(ir)));
395
502
  const lead = ir.analyses.clockSecond ? countedPhrase(ir, "second", "Sekunde", "Sekunden") + ", " : "";
396
- return lead + countedPhrase(ir, "minute", "Minute", "Minuten") + ", " + hours;
503
+ return lead + (strideFromSegments(fieldSegments(ir, "minute"), UNITS.minute, "") ?? countedPhrase(ir, "minute", "Minute", "Minuten")) + ", " + hours;
397
504
  }
398
505
  function renderMinuteFrequency(ir, plan, opts) {
399
506
  const segment = stepSegment(ir.analyses.segments.minute);
400
507
  const sep = opts.style.sep;
401
508
  const clean = cleanStep(segment, 60);
402
- const base = clean ? everyN(segment.interval, UNITS.minute) : countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde";
509
+ const base = stepClause(segment, UNITS.minute, "jeder Stunde");
403
510
  if (plan.hours.kind === "window") {
404
511
  const window = hourWindow(
405
512
  plan.hours.from,
@@ -410,7 +517,8 @@ function renderMinuteFrequency(ir, plan, opts) {
410
517
  return clean ? base + " " + window : base + ", " + window;
411
518
  }
412
519
  if (plan.hours.kind === "during") {
413
- return base + " " + duringHours(ir, plan.hours.times, sep);
520
+ const cadence = unevenHourCadence(ir);
521
+ return cadence ? base + ", " + cadence : base + " " + duringHours(ir, plan.hours.times, sep);
414
522
  }
415
523
  if (plan.hours.kind === "step") {
416
524
  return base + " " + everyNthHour(stepSegment(ir.analyses.segments.hour));
@@ -418,9 +526,126 @@ function renderMinuteFrequency(ir, plan, opts) {
418
526
  return base;
419
527
  }
420
528
  function hourStepPhrase(ir) {
529
+ const cadence = unevenHourCadence(ir);
530
+ if (cadence !== null) {
531
+ return cadence;
532
+ }
421
533
  const segment = stepSegment(ir.analyses.segments.hour);
422
534
  return cleanStep(segment, 24) ? everyN(segment.interval, UNITS.hour) : atHours(segment.fires);
423
535
  }
536
+ function hourStrideCadence(stride) {
537
+ const { start, interval, last } = stride;
538
+ const cadence = everyN(interval, UNITS.hour);
539
+ const tiles = 24 % interval === 0;
540
+ if (start === 0 && tiles) {
541
+ return cadence;
542
+ }
543
+ if (start < interval && tiles) {
544
+ return cadence + " ab " + start + " Uhr";
545
+ }
546
+ return cadence + " von " + start + " bis " + last + " Uhr";
547
+ }
548
+ function hourListStride(values) {
549
+ if (values.length < 2) {
550
+ return null;
551
+ }
552
+ const interval = values[1] - values[0];
553
+ if (interval < 2) {
554
+ return null;
555
+ }
556
+ for (let i = 2; i < values.length; i += 1) {
557
+ if (values[i] - values[i - 1] !== interval) {
558
+ return null;
559
+ }
560
+ }
561
+ if (values[0] !== 0 && values.length < 5) {
562
+ return null;
563
+ }
564
+ return { interval, last: values[values.length - 1], start: values[0] };
565
+ }
566
+ function offsetCleanStride(stride) {
567
+ return stride.start < stride.interval && 24 % stride.interval === 0;
568
+ }
569
+ function hourStride(ir) {
570
+ const segments = fieldSegments(ir, "hour");
571
+ if (!segments) {
572
+ return null;
573
+ }
574
+ if (segments.length === 1 && segments[0].kind === "step") {
575
+ const segment = segments[0];
576
+ if (segment.fires.length < 2) {
577
+ return null;
578
+ }
579
+ const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
580
+ return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
581
+ }
582
+ const values = singleValues(segments);
583
+ return values && hourListStride(values);
584
+ }
585
+ function unevenHourCadence(ir) {
586
+ const stride = hourStride(ir);
587
+ if (!stride || offsetCleanStride(stride)) {
588
+ return null;
589
+ }
590
+ return hourStrideCadence(stride);
591
+ }
592
+ function subMinuteSecond(ir) {
593
+ return ir.pattern.second === "*" || ir.shapes.second === "step";
594
+ }
595
+ function hourCadenceLead(ir, minute) {
596
+ if (minute === 0) {
597
+ if (subMinuteSecond(ir)) {
598
+ return secondsClause(ir, "jeder Minute") + " f\xFCr eine Minute";
599
+ }
600
+ return secondsClause(ir, "jeder Stunde");
601
+ }
602
+ const minutePhrase = "in Minute " + minute;
603
+ if (ir.pattern.second === "0") {
604
+ return minutePhrase;
605
+ }
606
+ return secondsClause(ir, "jeder Minute") + ", " + minutePhrase;
607
+ }
608
+ function hourCadence(ir, minute) {
609
+ const stride = hourStride(ir);
610
+ if (!stride) {
611
+ return null;
612
+ }
613
+ const fires = (stride.last - stride.start) / stride.interval + 1;
614
+ if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
615
+ return null;
616
+ }
617
+ const segment = fieldSegments(ir, "hour")[0];
618
+ const confined = minute === 0 && subMinuteSecond(ir) && fieldSegments(ir, "hour").length === 1 && segment.kind === "step" && confinedHourStride(segment);
619
+ if (confined) {
620
+ return secondsClause(ir, "jeder Minute") + " f\xFCr eine Minute " + everyNthHour(segment);
621
+ }
622
+ if (minute === 0 && ir.pattern.second === "0") {
623
+ return hourStrideCadence(stride);
624
+ }
625
+ return hourCadenceLead(ir, minute) + ", " + hourStrideCadence(stride);
626
+ }
627
+ function hourCadenceApplies(ir) {
628
+ if (ir.shapes.minute !== "single") {
629
+ return false;
630
+ }
631
+ const minute = +ir.pattern.minute;
632
+ return hourCadence(ir, minute) !== null || hourRangeCadence(ir, minute) !== null;
633
+ }
634
+ function hasHourWindow(ir) {
635
+ const segments = fieldSegments(ir, "hour");
636
+ return !!segments && segments.some(function range(segment) {
637
+ return segment.kind === "range";
638
+ });
639
+ }
640
+ function hourRangeCadence(ir, minute) {
641
+ if (minute !== 0 || !hasHourWindow(ir) || ir.pattern.second === "0") {
642
+ return null;
643
+ }
644
+ return hourCadenceLead(ir, minute) + ", " + hourRangeWindowTail(ir);
645
+ }
646
+ function hourRangeWindowTail(ir) {
647
+ return joinList(hourSegmentParts(ir, 0, 0, ":"));
648
+ }
424
649
  function renderHourRange(ir, plan, opts) {
425
650
  const window = hourWindow(
426
651
  plan.from,
@@ -434,9 +659,20 @@ function renderHourRange(ir, plan, opts) {
434
659
  if (plan.minuteForm === "lead" && ir.pattern.minute === "0") {
435
660
  return "st\xFCndlich " + window;
436
661
  }
437
- return countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde, " + window;
662
+ return (strideFromSegments(
663
+ fieldSegments(ir, "minute"),
664
+ UNITS.minute,
665
+ "jeder Stunde"
666
+ ) ?? countedPhrase(ir, "minute", "Minute", "Minuten") + " jeder Stunde") + ", " + window;
438
667
  }
439
668
  function renderClockTimes(ir, plan, opts) {
669
+ if (ir.shapes.minute === "single") {
670
+ const minute = +ir.pattern.minute;
671
+ const cadence = hourCadence(ir, minute) ?? hourRangeCadence(ir, minute);
672
+ if (cadence !== null) {
673
+ return cadence;
674
+ }
675
+ }
440
676
  return "um " + timesPhrase(plan.times, opts.style.sep);
441
677
  }
442
678
  var renderers = {
@@ -486,6 +722,9 @@ function isComposeMinuteZero(ir) {
486
722
  return ir.plan.kind === "composeSeconds" && composeMinuteZero(ir, ir.plan);
487
723
  }
488
724
  function needsDailyFrame(ir) {
725
+ if (hourCadenceApplies(ir)) {
726
+ return false;
727
+ }
489
728
  if (ir.plan.kind === "clockTimes" || isComposeMinuteZero(ir)) {
490
729
  return true;
491
730
  }