cronli5 0.3.4 → 0.8.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/README.md +63 -13
  3. package/cronli5.min.js +2 -2
  4. package/dist/cronli5.cjs +72 -9
  5. package/dist/cronli5.js +72 -9
  6. package/dist/lang/de.cjs +14 -6
  7. package/dist/lang/de.js +14 -6
  8. package/dist/lang/en.cjs +14 -6
  9. package/dist/lang/en.js +14 -6
  10. package/dist/lang/es.cjs +14 -6
  11. package/dist/lang/es.js +14 -6
  12. package/dist/lang/fi.cjs +14 -6
  13. package/dist/lang/fi.js +14 -6
  14. package/dist/lang/fr.cjs +1211 -0
  15. package/dist/lang/fr.js +1187 -0
  16. package/dist/lang/pt.cjs +1592 -0
  17. package/dist/lang/pt.js +1568 -0
  18. package/dist/lang/zh.cjs +58 -9
  19. package/dist/lang/zh.js +58 -9
  20. package/package.json +13 -2
  21. package/src/core/cadence.ts +25 -12
  22. package/src/core/index.ts +7 -3
  23. package/src/core/quartz.ts +97 -0
  24. package/src/core/schedule.ts +1 -0
  25. package/src/core/specs.ts +2 -2
  26. package/src/cronli5.ts +20 -3
  27. package/src/lang/de/index.ts +3 -2
  28. package/src/lang/en/index.ts +3 -2
  29. package/src/lang/es/index.ts +3 -2
  30. package/src/lang/fi/index.ts +3 -2
  31. package/src/lang/fr/dialects.ts +49 -0
  32. package/src/lang/fr/index.ts +2116 -0
  33. package/src/lang/fr/notes.md +280 -0
  34. package/src/lang/fr/status.json +8 -0
  35. package/src/lang/pt/dialects.ts +56 -0
  36. package/src/lang/pt/index.ts +2804 -0
  37. package/src/lang/pt/notes.md +199 -0
  38. package/src/lang/pt/status.json +8 -0
  39. package/src/lang/zh/index.ts +61 -5
  40. package/src/lang/zh/notes.md +16 -4
  41. package/src/lang/zh/status.json +10 -1
  42. package/src/types.ts +44 -0
  43. package/types/core/cadence.d.ts +1 -0
  44. package/types/core/quartz.d.ts +4 -0
  45. package/types/core/schedule.d.ts +1 -0
  46. package/types/cronli5.d.ts +4 -4
  47. package/types/lang/fr/dialects.d.ts +11 -0
  48. package/types/lang/fr/index.d.ts +4 -0
  49. package/types/lang/pt/dialects.d.ts +13 -0
  50. package/types/lang/pt/index.d.ts +4 -0
  51. package/types/types.d.ts +39 -0
package/dist/cronli5.js CHANGED
@@ -26,10 +26,10 @@ var fieldSpecs = {
26
26
  second: { cyclic: true, max: 59, min: 0, top: 59 },
27
27
  minute: { cyclic: true, max: 59, min: 0, top: 59 },
28
28
  hour: { cyclic: true, max: 23, min: 0, top: 23 },
29
- date: { aliases: { "?": "*" }, cyclic: true, max: 31, min: 1, top: 31 },
29
+ date: { cyclic: true, max: 31, min: 1, top: 31 },
30
30
  month: { cyclic: true, max: 12, min: 1, numbers: monthNumbers, top: 12 },
31
31
  weekday: {
32
- aliases: { "?": "*", L: "6" },
32
+ aliases: { L: "6" },
33
33
  cyclic: true,
34
34
  max: 7,
35
35
  min: 0,
@@ -326,6 +326,53 @@ function firstFire(segment, spec) {
326
326
  return start === "*" ? spec.min : toFieldNumber(start, spec.numbers);
327
327
  }
328
328
 
329
+ // src/core/quartz.ts
330
+ var quartzTokenMessage = "`?` is a Quartz token \u2014 pass { quartz: true } to enable Quartz semantics.";
331
+ function applyQuartz(cronPattern, quartz) {
332
+ if (!quartz) {
333
+ rejectQuartzToken(cronPattern.date);
334
+ rejectQuartzToken(cronPattern.weekday);
335
+ return;
336
+ }
337
+ if ("" + cronPattern.date === "?") {
338
+ cronPattern.date = "*";
339
+ }
340
+ if ("" + cronPattern.weekday === "?") {
341
+ cronPattern.weekday = "*";
342
+ return;
343
+ }
344
+ cronPattern.weekday = reindexWeekday("" + cronPattern.weekday);
345
+ }
346
+ function rejectQuartzToken(value) {
347
+ if ("" + value === "?") {
348
+ throw new Error(quartzTokenMessage);
349
+ }
350
+ }
351
+ function reindexWeekday(value) {
352
+ if (value === "*") {
353
+ return value;
354
+ }
355
+ return value.split(",").map(reindexSegment).join(",");
356
+ }
357
+ function reindexSegment(segment) {
358
+ const operator = /(#\d+|L)$/.exec(segment);
359
+ const suffix = operator ? operator[0] : "";
360
+ const core = suffix ? segment.slice(0, -suffix.length) : segment;
361
+ const step = core.split("/");
362
+ const range = step[0].split("-").map(reindexNumber).join("-");
363
+ const head = step.length === 2 ? range + "/" + step[1] : range;
364
+ return head + suffix;
365
+ }
366
+ function reindexNumber(token) {
367
+ if (!isNonNegativeInteger(token)) {
368
+ return token;
369
+ }
370
+ if (token === "0") {
371
+ throw new Error('`cronli5` was passed an invalid Quartz day-of-week value "0"; Quartz numbers weekdays 1 (Sunday) through 7 (Saturday).');
372
+ }
373
+ return "" + (+token - 1);
374
+ }
375
+
329
376
  // src/core/parse.ts
330
377
  function parseCronPattern(cronPattern, opts) {
331
378
  const isArray = cronPattern instanceof Array;
@@ -461,13 +508,20 @@ function singleValues(segments) {
461
508
  function offsetCleanStride(stride) {
462
509
  return stride.start < stride.interval && 24 % stride.interval === 0;
463
510
  }
511
+ function lastTileOf(start, interval, cycle) {
512
+ return cycle - 1 - (cycle - 1 - start) % interval;
513
+ }
464
514
  function renderStride(spec, parts) {
465
- const { start, interval, cycle } = spec;
466
- const tiles = cycle % interval === 0;
467
- if (start === 0 && tiles) {
515
+ const { start, interval, last, cycle } = spec;
516
+ const open = cycle % interval === 0 && last === lastTileOf(
517
+ start,
518
+ interval,
519
+ cycle
520
+ );
521
+ if (start === 0 && open) {
468
522
  return parts.bare();
469
523
  }
470
- if (start < interval && tiles) {
524
+ if (start < interval && open) {
471
525
  return parts.offset();
472
526
  }
473
527
  return parts.bounded();
@@ -859,6 +913,7 @@ function hourTimesPlan(hourField) {
859
913
  // src/core/index.ts
860
914
  function prepare(cronPattern, opts) {
861
915
  const pattern = parseCronPattern(cronPattern, opts);
916
+ applyQuartz(pattern, opts.quartz);
862
917
  applyQuartzAliases(pattern);
863
918
  validateCronPattern(pattern);
864
919
  return normalizeCronPattern(pattern);
@@ -987,6 +1042,7 @@ function normalizeOptions(options) {
987
1042
  return {
988
1043
  ampm: typeof options.ampm === "boolean" ? options.ampm : true,
989
1044
  lenient: !!options.lenient,
1045
+ quartz: !!options.quartz,
990
1046
  seconds: !!options.seconds,
991
1047
  short: !!options.short,
992
1048
  style: resolveDialect(options.dialect),
@@ -1579,7 +1635,7 @@ var renderers = {
1579
1635
  function renderStride2(stride, opts) {
1580
1636
  const { interval, start, last, cycle, unit, anchor } = stride;
1581
1637
  const cadence = "every " + getNumber(interval, opts) + " " + unit + "s";
1582
- return renderStride({ start, interval, cycle }, {
1638
+ return renderStride({ start, interval, last, cycle }, {
1583
1639
  bare: () => cadence,
1584
1640
  // A clean wrap from a non-zero offset: name the start, no endpoint.
1585
1641
  offset: () => cadence + " from " + getNumber(start, opts) + " " + pluralize(start, unit) + " past the " + anchor,
@@ -1630,7 +1686,7 @@ function stepHours(segment, opts) {
1630
1686
  function hourStrideCadence(stride, opts) {
1631
1687
  const { start, interval, last } = stride;
1632
1688
  const cadence = "every " + getNumber(interval, opts) + " hours";
1633
- return renderStride({ start, interval, cycle: 24 }, {
1689
+ return renderStride({ start, interval, last, cycle: 24 }, {
1634
1690
  bare: () => cadence,
1635
1691
  offset: () => cadence + " from " + getTime({ hour: start, minute: 0 }, opts),
1636
1692
  bounded: () => cadence + " from " + getTime({ hour: start, minute: 0 }, opts) + through(opts) + getTime({ hour: last, minute: 0 }, opts)
@@ -2289,7 +2345,14 @@ function interpretCronPattern(cronPattern, lang, opts) {
2289
2345
  const plan = lang.plan ? lang.plan(schedule, schedule.plan) : schedule.plan;
2290
2346
  return lang.describe({ ...schedule, plan }, opts);
2291
2347
  }
2292
- var cronli5_default = cronli5;
2348
+ function sentence(cronPattern, options) {
2349
+ return cronli5(cronPattern, { ...options, sentence: true });
2350
+ }
2351
+ function fragment(cronPattern, options) {
2352
+ return cronli5(cronPattern, { ...options, sentence: false });
2353
+ }
2354
+ var callable = Object.assign(cronli5, { sentence, fragment });
2355
+ var cronli5_default = callable;
2293
2356
  export {
2294
2357
  cronli5_default as default
2295
2358
  };
package/dist/lang/de.cjs CHANGED
@@ -77,13 +77,20 @@ function singleValues(segments) {
77
77
  function offsetCleanStride(stride) {
78
78
  return stride.start < stride.interval && 24 % stride.interval === 0;
79
79
  }
80
+ function lastTileOf(start, interval, cycle) {
81
+ return cycle - 1 - (cycle - 1 - start) % interval;
82
+ }
80
83
  function renderStride(spec, parts) {
81
- const { start, interval, cycle } = spec;
82
- const tiles = cycle % interval === 0;
83
- if (start === 0 && tiles) {
84
+ const { start, interval, last, cycle } = spec;
85
+ const open = cycle % interval === 0 && last === lastTileOf(
86
+ start,
87
+ interval,
88
+ cycle
89
+ );
90
+ if (start === 0 && open) {
84
91
  return parts.bare();
85
92
  }
86
- if (start < interval && tiles) {
93
+ if (start < interval && open) {
87
94
  return parts.offset();
88
95
  }
89
96
  return parts.bounded();
@@ -209,7 +216,7 @@ function renderStride2(stride) {
209
216
  const { interval, start, last, cycle, unit, anchor } = stride;
210
217
  const cadence = everyN(interval, unit);
211
218
  const tail = anchor ? " " + anchor : "";
212
- return renderStride({ start, interval, cycle }, {
219
+ return renderStride({ start, interval, last, cycle }, {
213
220
  bare: () => cadence,
214
221
  offset: () => cadence + " ab " + unit.singular + " " + start + tail,
215
222
  bounded: () => cadence + " von " + unit.singular + " " + start + " bis " + last + tail
@@ -667,7 +674,7 @@ function openOffsetCleanStride(schedule, segment) {
667
674
  function hourStrideCadence(stride) {
668
675
  const { start, interval, last } = stride;
669
676
  const cadence = everyN(interval, UNITS.hour);
670
- return renderStride({ start, interval, cycle: 24 }, {
677
+ return renderStride({ start, interval, last, cycle: 24 }, {
671
678
  bare: () => cadence,
672
679
  offset: () => cadence + " ab " + start + " Uhr",
673
680
  bounded: () => cadence + " von " + start + " bis " + last + " Uhr"
@@ -883,6 +890,7 @@ function normalizeOptions(options) {
883
890
  return {
884
891
  ampm: typeof options.ampm === "boolean" ? options.ampm : false,
885
892
  lenient: !!options.lenient,
893
+ quartz: !!options.quartz,
886
894
  seconds: !!options.seconds,
887
895
  short: !!options.short,
888
896
  style,
package/dist/lang/de.js CHANGED
@@ -51,13 +51,20 @@ function singleValues(segments) {
51
51
  function offsetCleanStride(stride) {
52
52
  return stride.start < stride.interval && 24 % stride.interval === 0;
53
53
  }
54
+ function lastTileOf(start, interval, cycle) {
55
+ return cycle - 1 - (cycle - 1 - start) % interval;
56
+ }
54
57
  function renderStride(spec, parts) {
55
- const { start, interval, cycle } = spec;
56
- const tiles = cycle % interval === 0;
57
- if (start === 0 && tiles) {
58
+ const { start, interval, last, cycle } = spec;
59
+ const open = cycle % interval === 0 && last === lastTileOf(
60
+ start,
61
+ interval,
62
+ cycle
63
+ );
64
+ if (start === 0 && open) {
58
65
  return parts.bare();
59
66
  }
60
- if (start < interval && tiles) {
67
+ if (start < interval && open) {
61
68
  return parts.offset();
62
69
  }
63
70
  return parts.bounded();
@@ -183,7 +190,7 @@ function renderStride2(stride) {
183
190
  const { interval, start, last, cycle, unit, anchor } = stride;
184
191
  const cadence = everyN(interval, unit);
185
192
  const tail = anchor ? " " + anchor : "";
186
- return renderStride({ start, interval, cycle }, {
193
+ return renderStride({ start, interval, last, cycle }, {
187
194
  bare: () => cadence,
188
195
  offset: () => cadence + " ab " + unit.singular + " " + start + tail,
189
196
  bounded: () => cadence + " von " + unit.singular + " " + start + " bis " + last + tail
@@ -641,7 +648,7 @@ function openOffsetCleanStride(schedule, segment) {
641
648
  function hourStrideCadence(stride) {
642
649
  const { start, interval, last } = stride;
643
650
  const cadence = everyN(interval, UNITS.hour);
644
- return renderStride({ start, interval, cycle: 24 }, {
651
+ return renderStride({ start, interval, last, cycle: 24 }, {
645
652
  bare: () => cadence,
646
653
  offset: () => cadence + " ab " + start + " Uhr",
647
654
  bounded: () => cadence + " von " + start + " bis " + last + " Uhr"
@@ -857,6 +864,7 @@ function normalizeOptions(options) {
857
864
  return {
858
865
  ampm: typeof options.ampm === "boolean" ? options.ampm : false,
859
866
  lenient: !!options.lenient,
867
+ quartz: !!options.quartz,
860
868
  seconds: !!options.seconds,
861
869
  short: !!options.short,
862
870
  style,
package/dist/lang/en.cjs CHANGED
@@ -59,13 +59,20 @@ function singleValues(segments) {
59
59
  function offsetCleanStride(stride) {
60
60
  return stride.start < stride.interval && 24 % stride.interval === 0;
61
61
  }
62
+ function lastTileOf(start, interval, cycle) {
63
+ return cycle - 1 - (cycle - 1 - start) % interval;
64
+ }
62
65
  function renderStride(spec, parts) {
63
- const { start, interval, cycle } = spec;
64
- const tiles = cycle % interval === 0;
65
- if (start === 0 && tiles) {
66
+ const { start, interval, last, cycle } = spec;
67
+ const open = cycle % interval === 0 && last === lastTileOf(
68
+ start,
69
+ interval,
70
+ cycle
71
+ );
72
+ if (start === 0 && open) {
66
73
  return parts.bare();
67
74
  }
68
- if (start < interval && tiles) {
75
+ if (start < interval && open) {
69
76
  return parts.offset();
70
77
  }
71
78
  return parts.bounded();
@@ -242,6 +249,7 @@ function normalizeOptions(options) {
242
249
  return {
243
250
  ampm: typeof options.ampm === "boolean" ? options.ampm : true,
244
251
  lenient: !!options.lenient,
252
+ quartz: !!options.quartz,
245
253
  seconds: !!options.seconds,
246
254
  short: !!options.short,
247
255
  style: resolveDialect(options.dialect),
@@ -834,7 +842,7 @@ var renderers = {
834
842
  function renderStride2(stride, opts) {
835
843
  const { interval, start, last, cycle, unit, anchor } = stride;
836
844
  const cadence = "every " + getNumber(interval, opts) + " " + unit + "s";
837
- return renderStride({ start, interval, cycle }, {
845
+ return renderStride({ start, interval, last, cycle }, {
838
846
  bare: () => cadence,
839
847
  // A clean wrap from a non-zero offset: name the start, no endpoint.
840
848
  offset: () => cadence + " from " + getNumber(start, opts) + " " + pluralize(start, unit) + " past the " + anchor,
@@ -885,7 +893,7 @@ function stepHours(segment, opts) {
885
893
  function hourStrideCadence(stride, opts) {
886
894
  const { start, interval, last } = stride;
887
895
  const cadence = "every " + getNumber(interval, opts) + " hours";
888
- return renderStride({ start, interval, cycle: 24 }, {
896
+ return renderStride({ start, interval, last, cycle: 24 }, {
889
897
  bare: () => cadence,
890
898
  offset: () => cadence + " from " + getTime({ hour: start, minute: 0 }, opts),
891
899
  bounded: () => cadence + " from " + getTime({ hour: start, minute: 0 }, opts) + through(opts) + getTime({ hour: last, minute: 0 }, opts)
package/dist/lang/en.js CHANGED
@@ -33,13 +33,20 @@ function singleValues(segments) {
33
33
  function offsetCleanStride(stride) {
34
34
  return stride.start < stride.interval && 24 % stride.interval === 0;
35
35
  }
36
+ function lastTileOf(start, interval, cycle) {
37
+ return cycle - 1 - (cycle - 1 - start) % interval;
38
+ }
36
39
  function renderStride(spec, parts) {
37
- const { start, interval, cycle } = spec;
38
- const tiles = cycle % interval === 0;
39
- if (start === 0 && tiles) {
40
+ const { start, interval, last, cycle } = spec;
41
+ const open = cycle % interval === 0 && last === lastTileOf(
42
+ start,
43
+ interval,
44
+ cycle
45
+ );
46
+ if (start === 0 && open) {
40
47
  return parts.bare();
41
48
  }
42
- if (start < interval && tiles) {
49
+ if (start < interval && open) {
43
50
  return parts.offset();
44
51
  }
45
52
  return parts.bounded();
@@ -216,6 +223,7 @@ function normalizeOptions(options) {
216
223
  return {
217
224
  ampm: typeof options.ampm === "boolean" ? options.ampm : true,
218
225
  lenient: !!options.lenient,
226
+ quartz: !!options.quartz,
219
227
  seconds: !!options.seconds,
220
228
  short: !!options.short,
221
229
  style: resolveDialect(options.dialect),
@@ -808,7 +816,7 @@ var renderers = {
808
816
  function renderStride2(stride, opts) {
809
817
  const { interval, start, last, cycle, unit, anchor } = stride;
810
818
  const cadence = "every " + getNumber(interval, opts) + " " + unit + "s";
811
- return renderStride({ start, interval, cycle }, {
819
+ return renderStride({ start, interval, last, cycle }, {
812
820
  bare: () => cadence,
813
821
  // A clean wrap from a non-zero offset: name the start, no endpoint.
814
822
  offset: () => cadence + " from " + getNumber(start, opts) + " " + pluralize(start, unit) + " past the " + anchor,
@@ -859,7 +867,7 @@ function stepHours(segment, opts) {
859
867
  function hourStrideCadence(stride, opts) {
860
868
  const { start, interval, last } = stride;
861
869
  const cadence = "every " + getNumber(interval, opts) + " hours";
862
- return renderStride({ start, interval, cycle: 24 }, {
870
+ return renderStride({ start, interval, last, cycle: 24 }, {
863
871
  bare: () => cadence,
864
872
  offset: () => cadence + " from " + getTime({ hour: start, minute: 0 }, opts),
865
873
  bounded: () => cadence + " from " + getTime({ hour: start, minute: 0 }, opts) + through(opts) + getTime({ hour: last, minute: 0 }, opts)
package/dist/lang/es.cjs CHANGED
@@ -101,13 +101,20 @@ function singleValues(segments) {
101
101
  function offsetCleanStride(stride) {
102
102
  return stride.start < stride.interval && 24 % stride.interval === 0;
103
103
  }
104
+ function lastTileOf(start, interval, cycle) {
105
+ return cycle - 1 - (cycle - 1 - start) % interval;
106
+ }
104
107
  function renderStride(spec, parts) {
105
- const { start, interval, cycle } = spec;
106
- const tiles = cycle % interval === 0;
107
- if (start === 0 && tiles) {
108
+ const { start, interval, last, cycle } = spec;
109
+ const open = cycle % interval === 0 && last === lastTileOf(
110
+ start,
111
+ interval,
112
+ cycle
113
+ );
114
+ if (start === 0 && open) {
108
115
  return parts.bare();
109
116
  }
110
- if (start < interval && tiles) {
117
+ if (start < interval && open) {
111
118
  return parts.offset();
112
119
  }
113
120
  return parts.bounded();
@@ -224,6 +231,7 @@ function normalizeOptions(options) {
224
231
  // 12-hour for Mexico/US); an explicit `{ampm}` option overrides it.
225
232
  ampm: typeof options.ampm === "boolean" ? options.ampm : style.ampm,
226
233
  lenient: !!options.lenient,
234
+ quartz: !!options.quartz,
227
235
  seconds: !!options.seconds,
228
236
  short: !!options.short,
229
237
  style,
@@ -815,7 +823,7 @@ function renderStride2(stride, opts) {
815
823
  const { interval, start, last, cycle, unit, anchor } = stride;
816
824
  const cadence = "cada " + numero(interval, opts) + " " + unit + "s";
817
825
  const tail = anchor ? " de cada " + anchor : "";
818
- return renderStride({ start, interval, cycle }, {
826
+ return renderStride({ start, interval, last, cycle }, {
819
827
  bare: () => cadence,
820
828
  offset: () => cadence + " a partir del " + unit + " " + start + tail,
821
829
  bounded: () => cadence + " del " + unit + " " + start + " al " + last + tail
@@ -860,7 +868,7 @@ function stepHours(segment, opts) {
860
868
  function hourStrideCadence(stride, opts) {
861
869
  const { start, interval, last } = stride;
862
870
  const cadence = "cada " + numero(interval, opts) + " horas";
863
- return renderStride({ start, interval, cycle: 24 }, {
871
+ return renderStride({ start, interval, last, cycle: 24 }, {
864
872
  bare: () => cadence,
865
873
  offset: () => cadence + " a partir de " + timePhrase(start, 0, null, opts),
866
874
  bounded: () => cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts)
package/dist/lang/es.js CHANGED
@@ -75,13 +75,20 @@ function singleValues(segments) {
75
75
  function offsetCleanStride(stride) {
76
76
  return stride.start < stride.interval && 24 % stride.interval === 0;
77
77
  }
78
+ function lastTileOf(start, interval, cycle) {
79
+ return cycle - 1 - (cycle - 1 - start) % interval;
80
+ }
78
81
  function renderStride(spec, parts) {
79
- const { start, interval, cycle } = spec;
80
- const tiles = cycle % interval === 0;
81
- if (start === 0 && tiles) {
82
+ const { start, interval, last, cycle } = spec;
83
+ const open = cycle % interval === 0 && last === lastTileOf(
84
+ start,
85
+ interval,
86
+ cycle
87
+ );
88
+ if (start === 0 && open) {
82
89
  return parts.bare();
83
90
  }
84
- if (start < interval && tiles) {
91
+ if (start < interval && open) {
85
92
  return parts.offset();
86
93
  }
87
94
  return parts.bounded();
@@ -198,6 +205,7 @@ function normalizeOptions(options) {
198
205
  // 12-hour for Mexico/US); an explicit `{ampm}` option overrides it.
199
206
  ampm: typeof options.ampm === "boolean" ? options.ampm : style.ampm,
200
207
  lenient: !!options.lenient,
208
+ quartz: !!options.quartz,
201
209
  seconds: !!options.seconds,
202
210
  short: !!options.short,
203
211
  style,
@@ -789,7 +797,7 @@ function renderStride2(stride, opts) {
789
797
  const { interval, start, last, cycle, unit, anchor } = stride;
790
798
  const cadence = "cada " + numero(interval, opts) + " " + unit + "s";
791
799
  const tail = anchor ? " de cada " + anchor : "";
792
- return renderStride({ start, interval, cycle }, {
800
+ return renderStride({ start, interval, last, cycle }, {
793
801
  bare: () => cadence,
794
802
  offset: () => cadence + " a partir del " + unit + " " + start + tail,
795
803
  bounded: () => cadence + " del " + unit + " " + start + " al " + last + tail
@@ -834,7 +842,7 @@ function stepHours(segment, opts) {
834
842
  function hourStrideCadence(stride, opts) {
835
843
  const { start, interval, last } = stride;
836
844
  const cadence = "cada " + numero(interval, opts) + " horas";
837
- return renderStride({ start, interval, cycle: 24 }, {
845
+ return renderStride({ start, interval, last, cycle: 24 }, {
838
846
  bare: () => cadence,
839
847
  offset: () => cadence + " a partir de " + timePhrase(start, 0, null, opts),
840
848
  bounded: () => cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts)
package/dist/lang/fi.cjs CHANGED
@@ -101,13 +101,20 @@ function singleValues(segments) {
101
101
  function offsetCleanStride(stride) {
102
102
  return stride.start < stride.interval && 24 % stride.interval === 0;
103
103
  }
104
+ function lastTileOf(start, interval, cycle) {
105
+ return cycle - 1 - (cycle - 1 - start) % interval;
106
+ }
104
107
  function renderStride(spec, parts) {
105
- const { start, interval, cycle } = spec;
106
- const tiles = cycle % interval === 0;
107
- if (start === 0 && tiles) {
108
+ const { start, interval, last, cycle } = spec;
109
+ const open = cycle % interval === 0 && last === lastTileOf(
110
+ start,
111
+ interval,
112
+ cycle
113
+ );
114
+ if (start === 0 && open) {
108
115
  return parts.bare();
109
116
  }
110
- if (start < interval && tiles) {
117
+ if (start < interval && open) {
111
118
  return parts.offset();
112
119
  }
113
120
  return parts.bounded();
@@ -301,6 +308,7 @@ function normalizeOptions(options) {
301
308
  return {
302
309
  ampm: false,
303
310
  lenient: !!options.lenient,
311
+ quartz: !!options.quartz,
304
312
  seconds: !!options.seconds,
305
313
  short: !!options.short,
306
314
  style: resolveDialect(options.dialect),
@@ -750,7 +758,7 @@ var renderers = {
750
758
  function renderStride2(stride, opts) {
751
759
  const { interval, start, last, cycle, unit } = stride;
752
760
  const cadence = genitive(interval, opts) + " " + unit.gen + " v\xE4lein";
753
- return renderStride({ start, interval, cycle }, {
761
+ return renderStride({ start, interval, last, cycle }, {
754
762
  bare: () => cadence,
755
763
  offset: () => cadence + " " + unit.anchor + " " + unit.ela + " " + start + " alkaen",
756
764
  bounded: () => cadence + " " + unit.ela + " " + start + " " + unit.ill + " " + last
@@ -795,7 +803,7 @@ function stepHours(segment, opts) {
795
803
  function hourStrideCadence(stride, opts) {
796
804
  const { start, interval, last } = stride;
797
805
  const cadence = genitive(interval, opts) + " tunnin v\xE4lein";
798
- return renderStride({ start, interval, cycle: 24 }, {
806
+ return renderStride({ start, interval, last, cycle: 24 }, {
799
807
  bare: () => cadence,
800
808
  offset: () => cadence + " klo " + hourElatives[start] + " alkaen",
801
809
  bounded: () => cadence + " " + kloRange({ hour: start, minute: 0 }, { hour: last, minute: 0 }, opts)
package/dist/lang/fi.js CHANGED
@@ -75,13 +75,20 @@ function singleValues(segments) {
75
75
  function offsetCleanStride(stride) {
76
76
  return stride.start < stride.interval && 24 % stride.interval === 0;
77
77
  }
78
+ function lastTileOf(start, interval, cycle) {
79
+ return cycle - 1 - (cycle - 1 - start) % interval;
80
+ }
78
81
  function renderStride(spec, parts) {
79
- const { start, interval, cycle } = spec;
80
- const tiles = cycle % interval === 0;
81
- if (start === 0 && tiles) {
82
+ const { start, interval, last, cycle } = spec;
83
+ const open = cycle % interval === 0 && last === lastTileOf(
84
+ start,
85
+ interval,
86
+ cycle
87
+ );
88
+ if (start === 0 && open) {
82
89
  return parts.bare();
83
90
  }
84
- if (start < interval && tiles) {
91
+ if (start < interval && open) {
85
92
  return parts.offset();
86
93
  }
87
94
  return parts.bounded();
@@ -275,6 +282,7 @@ function normalizeOptions(options) {
275
282
  return {
276
283
  ampm: false,
277
284
  lenient: !!options.lenient,
285
+ quartz: !!options.quartz,
278
286
  seconds: !!options.seconds,
279
287
  short: !!options.short,
280
288
  style: resolveDialect(options.dialect),
@@ -724,7 +732,7 @@ var renderers = {
724
732
  function renderStride2(stride, opts) {
725
733
  const { interval, start, last, cycle, unit } = stride;
726
734
  const cadence = genitive(interval, opts) + " " + unit.gen + " v\xE4lein";
727
- return renderStride({ start, interval, cycle }, {
735
+ return renderStride({ start, interval, last, cycle }, {
728
736
  bare: () => cadence,
729
737
  offset: () => cadence + " " + unit.anchor + " " + unit.ela + " " + start + " alkaen",
730
738
  bounded: () => cadence + " " + unit.ela + " " + start + " " + unit.ill + " " + last
@@ -769,7 +777,7 @@ function stepHours(segment, opts) {
769
777
  function hourStrideCadence(stride, opts) {
770
778
  const { start, interval, last } = stride;
771
779
  const cadence = genitive(interval, opts) + " tunnin v\xE4lein";
772
- return renderStride({ start, interval, cycle: 24 }, {
780
+ return renderStride({ start, interval, last, cycle: 24 }, {
773
781
  bare: () => cadence,
774
782
  offset: () => cadence + " klo " + hourElatives[start] + " alkaen",
775
783
  bounded: () => cadence + " " + kloRange({ hour: start, minute: 0 }, { hour: last, minute: 0 }, opts)