cronli5 0.1.1 → 0.1.4

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/en.cjs CHANGED
@@ -131,20 +131,6 @@ var weekdayNames = [
131
131
  ["Friday", "Fri"],
132
132
  ["Saturday", "Sat"]
133
133
  ];
134
- var monthAbbreviations = {
135
- JAN: monthNames[1],
136
- FEB: monthNames[2],
137
- MAR: monthNames[3],
138
- APR: monthNames[4],
139
- MAY: monthNames[5],
140
- JUN: monthNames[6],
141
- JUL: monthNames[7],
142
- AUG: monthNames[8],
143
- SEP: monthNames[9],
144
- OCT: monthNames[10],
145
- NOV: monthNames[11],
146
- DEC: monthNames[12]
147
- };
148
134
  var weekdayAbbreviations = {
149
135
  SUN: weekdayNames[0],
150
136
  MON: weekdayNames[1],
@@ -194,8 +180,37 @@ function renderSecondsWithinMinute(ir, plan, opts) {
194
180
  return secondsLeadClause(ir, opts) + ", " + minuteWord + " " + minuteUnit + " past the hour, every hour" + trailingQualifier(ir, opts);
195
181
  }
196
182
  function renderComposeSeconds(ir, plan, opts) {
183
+ if (plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step")) {
184
+ const minute = plan.rest.times[0].minute;
185
+ if (+minute === 0) {
186
+ return secondsLeadClause(ir, opts) + " for one minute at " + durationHours(ir, plan.rest, opts);
187
+ }
188
+ return secondsLeadClause(ir, opts) + " of " + clockTimesOf(ir, plan.rest, opts);
189
+ }
190
+ if (ir.shapes.second === "wildcard" && plan.rest.kind === "minuteFrequency" && plan.rest.hours.kind === "none" && ir.pattern.minute === "*/2") {
191
+ return "every second of every other minute" + trailingQualifier(ir, opts);
192
+ }
197
193
  return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
198
194
  }
195
+ function durationHours(ir, plan, opts) {
196
+ const hours = plan.times.map(function clock(time) {
197
+ return getTime({ hour: time.hour, minute: 0 }, opts);
198
+ });
199
+ const trail = dayQualifier(ir, leadingWords, opts);
200
+ return joinList(hours, opts) + (trail && ", " + trail);
201
+ }
202
+ function clockTimesOf(ir, plan, opts) {
203
+ const times = plan.times.map(function clock(time) {
204
+ return getTime({
205
+ hour: time.hour,
206
+ minute: time.minute,
207
+ second: time.second,
208
+ explicit: true
209
+ }, opts);
210
+ });
211
+ const trail = dayQualifier(ir, leadingWords, opts);
212
+ return joinList(times, opts) + (trail && ", " + trail);
213
+ }
199
214
  function secondsLeadClause(ir, opts) {
200
215
  const secondField = ir.pattern.second;
201
216
  const shape = ir.shapes.second;
@@ -260,6 +275,9 @@ function renderMinuteFrequency(ir, plan, opts) {
260
275
  return phrase + trailingQualifier(ir, opts);
261
276
  }
262
277
  function renderMinuteSpanInHour(ir, plan, opts) {
278
+ if (ir.pattern.minute === "*") {
279
+ return "every minute of the " + getTime({ hour: plan.hour, minute: 0 }, opts) + " hour" + trailingQualifier(ir, opts);
280
+ }
263
281
  return "every minute from " + getTime({ hour: plan.hour, minute: plan.span[0] }, opts) + through(opts) + getTime({ hour: plan.hour, minute: plan.span[1] }, opts) + trailingQualifier(ir, opts);
264
282
  }
265
283
  function renderMinutesAcrossHours(ir, plan, opts) {
@@ -431,13 +449,7 @@ function stepCycle60(segment, unit, anchor, opts) {
431
449
  }
432
450
  return "every " + getNumber(interval, opts) + " " + unit + "s from " + getNumber(start, opts) + " " + pluralize(start, unit) + " past the " + anchor;
433
451
  }
434
- if (60 % interval === 0) {
435
- return "every " + getNumber(interval, opts) + " " + unit + "s";
436
- }
437
- if (segment.fires.length <= 2) {
438
- return listPastThe(numberWords(segment.fires, opts), unit, anchor, opts);
439
- }
440
- return "every " + getNumber(interval, opts) + " " + unit + "s past the " + anchor;
452
+ return "every " + getNumber(interval, opts) + " " + unit + "s";
441
453
  }
442
454
  function stepHours(segment, opts) {
443
455
  if (segment.startToken.indexOf("-") !== -1) {
@@ -445,15 +457,12 @@ function stepHours(segment, opts) {
445
457
  }
446
458
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
447
459
  const interval = segment.interval;
448
- if (start === 0 && 24 % interval === 0) {
460
+ if (start === 0) {
449
461
  return "every " + getNumber(interval, opts) + " hours";
450
462
  }
451
463
  if (segment.fires.length <= 3) {
452
464
  return "at " + hourTimes(segment.fires, opts);
453
465
  }
454
- if (start === 0) {
455
- return "every " + getNumber(interval, opts) + " hours from midnight";
456
- }
457
466
  return "every " + getNumber(interval, opts) + " hours from " + getTime({ hour: start, minute: 0 }, opts);
458
467
  }
459
468
  function seriesNumber(values, opts) {
@@ -767,7 +776,7 @@ function stepYears(yearField, opts) {
767
776
  return phrase;
768
777
  }
769
778
  function getTime(time, opts) {
770
- const { hour, minute, plain } = time;
779
+ const { hour, minute, plain, explicit } = time;
771
780
  const second = typeof time.second === "number" && time.second > 0 ? time.second : 0;
772
781
  if (!opts.ampm) {
773
782
  return clockDigits({
@@ -776,12 +785,12 @@ function getTime(time, opts) {
776
785
  second
777
786
  }, { pad: true, sep: opts.style.sep });
778
787
  }
779
- return twelveHourTime({ hour, minute, second, plain }, opts);
788
+ return twelveHourTime({ hour, minute, second, plain, explicit }, opts);
780
789
  }
781
790
  function twelveHourTime(time, opts) {
782
- const { hour, minute, second, plain } = time;
791
+ const { hour, minute, second, plain, explicit } = time;
783
792
  const style = opts.style;
784
- if (!plain && +minute === 0 && !second) {
793
+ if (!plain && !explicit && +minute === 0 && !second) {
785
794
  if (+hour === 0) {
786
795
  return style.midnight;
787
796
  }
@@ -791,7 +800,7 @@ function twelveHourTime(time, opts) {
791
800
  }
792
801
  const digits = clockDigits(
793
802
  { hour: hour % 12 || 12, minute, second },
794
- { lean: true, sep: style.sep }
803
+ { lean: !explicit, sep: style.sep }
795
804
  );
796
805
  return digits + (style.closeUp ? "" : " ") + (hour < 12 ? style.am : style.pm);
797
806
  }
@@ -814,7 +823,7 @@ function getOrdinal(n) {
814
823
  return n + suffix;
815
824
  }
816
825
  function getMonth(m, opts) {
817
- const month = monthNames[m] || monthAbbreviations[m];
826
+ const month = monthNames[+m];
818
827
  return month && month[opts.short ? 1 : 0];
819
828
  }
820
829
  function getWeekday(d, opts) {
@@ -827,7 +836,9 @@ var en = {
827
836
  fallback: "an unrecognizable cron pattern",
828
837
  options: normalizeOptions,
829
838
  reboot: "at system startup",
830
- sentence: (description) => "Runs " + description + "."
839
+ // A description ending in an abbreviation already carries its period
840
+ // ("…9 a.m."), so closing the sentence must not double it.
841
+ sentence: (description) => "Runs " + description + (description.endsWith(".") ? "" : ".")
831
842
  };
832
843
  var index_default = en;
833
844
  module.exports = module.exports.default;
package/dist/lang/en.js CHANGED
@@ -105,20 +105,6 @@ var weekdayNames = [
105
105
  ["Friday", "Fri"],
106
106
  ["Saturday", "Sat"]
107
107
  ];
108
- var monthAbbreviations = {
109
- JAN: monthNames[1],
110
- FEB: monthNames[2],
111
- MAR: monthNames[3],
112
- APR: monthNames[4],
113
- MAY: monthNames[5],
114
- JUN: monthNames[6],
115
- JUL: monthNames[7],
116
- AUG: monthNames[8],
117
- SEP: monthNames[9],
118
- OCT: monthNames[10],
119
- NOV: monthNames[11],
120
- DEC: monthNames[12]
121
- };
122
108
  var weekdayAbbreviations = {
123
109
  SUN: weekdayNames[0],
124
110
  MON: weekdayNames[1],
@@ -168,8 +154,37 @@ function renderSecondsWithinMinute(ir, plan, opts) {
168
154
  return secondsLeadClause(ir, opts) + ", " + minuteWord + " " + minuteUnit + " past the hour, every hour" + trailingQualifier(ir, opts);
169
155
  }
170
156
  function renderComposeSeconds(ir, plan, opts) {
157
+ if (plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step")) {
158
+ const minute = plan.rest.times[0].minute;
159
+ if (+minute === 0) {
160
+ return secondsLeadClause(ir, opts) + " for one minute at " + durationHours(ir, plan.rest, opts);
161
+ }
162
+ return secondsLeadClause(ir, opts) + " of " + clockTimesOf(ir, plan.rest, opts);
163
+ }
164
+ if (ir.shapes.second === "wildcard" && plan.rest.kind === "minuteFrequency" && plan.rest.hours.kind === "none" && ir.pattern.minute === "*/2") {
165
+ return "every second of every other minute" + trailingQualifier(ir, opts);
166
+ }
171
167
  return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
172
168
  }
169
+ function durationHours(ir, plan, opts) {
170
+ const hours = plan.times.map(function clock(time) {
171
+ return getTime({ hour: time.hour, minute: 0 }, opts);
172
+ });
173
+ const trail = dayQualifier(ir, leadingWords, opts);
174
+ return joinList(hours, opts) + (trail && ", " + trail);
175
+ }
176
+ function clockTimesOf(ir, plan, opts) {
177
+ const times = plan.times.map(function clock(time) {
178
+ return getTime({
179
+ hour: time.hour,
180
+ minute: time.minute,
181
+ second: time.second,
182
+ explicit: true
183
+ }, opts);
184
+ });
185
+ const trail = dayQualifier(ir, leadingWords, opts);
186
+ return joinList(times, opts) + (trail && ", " + trail);
187
+ }
173
188
  function secondsLeadClause(ir, opts) {
174
189
  const secondField = ir.pattern.second;
175
190
  const shape = ir.shapes.second;
@@ -234,6 +249,9 @@ function renderMinuteFrequency(ir, plan, opts) {
234
249
  return phrase + trailingQualifier(ir, opts);
235
250
  }
236
251
  function renderMinuteSpanInHour(ir, plan, opts) {
252
+ if (ir.pattern.minute === "*") {
253
+ return "every minute of the " + getTime({ hour: plan.hour, minute: 0 }, opts) + " hour" + trailingQualifier(ir, opts);
254
+ }
237
255
  return "every minute from " + getTime({ hour: plan.hour, minute: plan.span[0] }, opts) + through(opts) + getTime({ hour: plan.hour, minute: plan.span[1] }, opts) + trailingQualifier(ir, opts);
238
256
  }
239
257
  function renderMinutesAcrossHours(ir, plan, opts) {
@@ -405,13 +423,7 @@ function stepCycle60(segment, unit, anchor, opts) {
405
423
  }
406
424
  return "every " + getNumber(interval, opts) + " " + unit + "s from " + getNumber(start, opts) + " " + pluralize(start, unit) + " past the " + anchor;
407
425
  }
408
- if (60 % interval === 0) {
409
- return "every " + getNumber(interval, opts) + " " + unit + "s";
410
- }
411
- if (segment.fires.length <= 2) {
412
- return listPastThe(numberWords(segment.fires, opts), unit, anchor, opts);
413
- }
414
- return "every " + getNumber(interval, opts) + " " + unit + "s past the " + anchor;
426
+ return "every " + getNumber(interval, opts) + " " + unit + "s";
415
427
  }
416
428
  function stepHours(segment, opts) {
417
429
  if (segment.startToken.indexOf("-") !== -1) {
@@ -419,15 +431,12 @@ function stepHours(segment, opts) {
419
431
  }
420
432
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
421
433
  const interval = segment.interval;
422
- if (start === 0 && 24 % interval === 0) {
434
+ if (start === 0) {
423
435
  return "every " + getNumber(interval, opts) + " hours";
424
436
  }
425
437
  if (segment.fires.length <= 3) {
426
438
  return "at " + hourTimes(segment.fires, opts);
427
439
  }
428
- if (start === 0) {
429
- return "every " + getNumber(interval, opts) + " hours from midnight";
430
- }
431
440
  return "every " + getNumber(interval, opts) + " hours from " + getTime({ hour: start, minute: 0 }, opts);
432
441
  }
433
442
  function seriesNumber(values, opts) {
@@ -741,7 +750,7 @@ function stepYears(yearField, opts) {
741
750
  return phrase;
742
751
  }
743
752
  function getTime(time, opts) {
744
- const { hour, minute, plain } = time;
753
+ const { hour, minute, plain, explicit } = time;
745
754
  const second = typeof time.second === "number" && time.second > 0 ? time.second : 0;
746
755
  if (!opts.ampm) {
747
756
  return clockDigits({
@@ -750,12 +759,12 @@ function getTime(time, opts) {
750
759
  second
751
760
  }, { pad: true, sep: opts.style.sep });
752
761
  }
753
- return twelveHourTime({ hour, minute, second, plain }, opts);
762
+ return twelveHourTime({ hour, minute, second, plain, explicit }, opts);
754
763
  }
755
764
  function twelveHourTime(time, opts) {
756
- const { hour, minute, second, plain } = time;
765
+ const { hour, minute, second, plain, explicit } = time;
757
766
  const style = opts.style;
758
- if (!plain && +minute === 0 && !second) {
767
+ if (!plain && !explicit && +minute === 0 && !second) {
759
768
  if (+hour === 0) {
760
769
  return style.midnight;
761
770
  }
@@ -765,7 +774,7 @@ function twelveHourTime(time, opts) {
765
774
  }
766
775
  const digits = clockDigits(
767
776
  { hour: hour % 12 || 12, minute, second },
768
- { lean: true, sep: style.sep }
777
+ { lean: !explicit, sep: style.sep }
769
778
  );
770
779
  return digits + (style.closeUp ? "" : " ") + (hour < 12 ? style.am : style.pm);
771
780
  }
@@ -788,7 +797,7 @@ function getOrdinal(n) {
788
797
  return n + suffix;
789
798
  }
790
799
  function getMonth(m, opts) {
791
- const month = monthNames[m] || monthAbbreviations[m];
800
+ const month = monthNames[+m];
792
801
  return month && month[opts.short ? 1 : 0];
793
802
  }
794
803
  function getWeekday(d, opts) {
@@ -801,7 +810,9 @@ var en = {
801
810
  fallback: "an unrecognizable cron pattern",
802
811
  options: normalizeOptions,
803
812
  reboot: "at system startup",
804
- sentence: (description) => "Runs " + description + "."
813
+ // A description ending in an abbreviation already carries its period
814
+ // ("…9 a.m."), so closing the sentence must not double it.
815
+ sentence: (description) => "Runs " + description + (description.endsWith(".") ? "" : ".")
805
816
  };
806
817
  var index_default = en;
807
818
  export {
package/dist/lang/es.cjs CHANGED
@@ -40,6 +40,26 @@ function clockDigits(time, { sep, pad: padHour, lean }) {
40
40
  return head + sep + pad(time.minute) + (time.second ? sep + pad(time.second) : "");
41
41
  }
42
42
 
43
+ // src/core/specs.ts
44
+ var weekdayNumbers = {
45
+ SUN: 0,
46
+ MON: 1,
47
+ TUE: 2,
48
+ WED: 3,
49
+ THU: 4,
50
+ FRI: 5,
51
+ SAT: 6
52
+ };
53
+
54
+ // src/core/util.ts
55
+ function isNonNegativeInteger(value) {
56
+ const digits = /^\d+$/;
57
+ return digits.test(value);
58
+ }
59
+ function toFieldNumber(token, numberMap) {
60
+ return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
61
+ }
62
+
43
63
  // src/lang/es/dialects.ts
44
64
  var es = {
45
65
  ampm: false,
@@ -111,29 +131,6 @@ var weekdayNames = [
111
131
  "viernes",
112
132
  "s\xE1bado"
113
133
  ];
114
- var monthTokens = {
115
- JAN: 1,
116
- FEB: 2,
117
- MAR: 3,
118
- APR: 4,
119
- MAY: 5,
120
- JUN: 6,
121
- JUL: 7,
122
- AUG: 8,
123
- SEP: 9,
124
- OCT: 10,
125
- NOV: 11,
126
- DEC: 12
127
- };
128
- var weekdayTokens = {
129
- SUN: 0,
130
- MON: 1,
131
- TUE: 2,
132
- WED: 3,
133
- THU: 4,
134
- FRI: 5,
135
- SAT: 6
136
- };
137
134
  var nthWeekdayNames = [null, "primer", "segundo", "tercer", "cuarto", "quinto"];
138
135
  function normalizeOptions(options) {
139
136
  options = options || {};
@@ -177,6 +174,9 @@ function renderSecondsWithinMinute(ir, plan, opts) {
177
174
  return secondsLeadClause(ir, opts) + ", en el minuto " + minuteField + " de cada hora" + trailingQualifier(ir, opts);
178
175
  }
179
176
  function renderComposeSeconds(ir, plan, opts) {
177
+ if (plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step")) {
178
+ return pinnedMinuteSeconds(ir, plan.rest, opts);
179
+ }
180
180
  if (plan.rest.kind === "clockTimes" && ir.shapes.second === "list") {
181
181
  const clockPhrases = plan.rest.times.map(function clock(time) {
182
182
  return atTime(timePhrase(time.hour, time.minute, null, opts));
@@ -196,6 +196,14 @@ function renderComposeSeconds(ir, plan, opts) {
196
196
  }
197
197
  return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
198
198
  }
199
+ function pinnedMinuteSeconds(ir, rest, opts) {
200
+ const dayTrail = leadingQualifier(ir, opts).trimEnd();
201
+ const trail = dayTrail ? ", " + dayTrail : "";
202
+ if (+rest.times[0].minute === 0) {
203
+ return secondsLeadClause(ir, opts) + " durante un minuto " + durationHourList(rest.times, opts) + trail;
204
+ }
205
+ return secondsLeadClause(ir, opts) + " de " + explicitClockList(rest.times, opts) + trail;
206
+ }
199
207
  function secondsLeadClause(ir, opts) {
200
208
  const secondField = ir.pattern.second;
201
209
  const shape = ir.shapes.second;
@@ -304,6 +312,9 @@ function renderMinuteFrequency(ir, plan, opts) {
304
312
  return phrase + trailingQualifier(ir, opts);
305
313
  }
306
314
  function renderMinuteSpanInHour(ir, plan, opts) {
315
+ if (ir.pattern.minute === "*") {
316
+ return "cada minuto de la hora " + fromTime(timePhrase(plan.hour, 0, null, opts)) + trailingQualifier(ir, opts);
317
+ }
307
318
  return "cada minuto " + timeRange(
308
319
  { hour: plan.hour, minute: plan.span[0] },
309
320
  { hour: plan.hour, minute: plan.span[1] },
@@ -420,6 +431,45 @@ function renderClockTimes(ir, plan, opts) {
420
431
  });
421
432
  return leadingQualifier(ir, opts) + groupClockTimes(phrases);
422
433
  }
434
+ function explicitClockList(times, opts) {
435
+ const phrases = times.map(function clock(time) {
436
+ return atTime(explicitTimePhrase(time.hour, time.minute, opts));
437
+ });
438
+ const grouped = groupClockTimes(phrases);
439
+ return grouped.startsWith("a ") ? grouped.slice(2) : grouped;
440
+ }
441
+ function durationHourList(times, opts) {
442
+ const phrases = times.map(function clock(time) {
443
+ return atTime(bareHourPhrase(time.hour, opts));
444
+ });
445
+ return groupClockTimes(phrases);
446
+ }
447
+ function bareHourPhrase(hour, opts) {
448
+ if (opts.ampm) {
449
+ return timePhrase(hour, 0, null, opts);
450
+ }
451
+ if (+hour === 0) {
452
+ return "medianoche";
453
+ }
454
+ if (+hour === 12) {
455
+ return "mediod\xEDa";
456
+ }
457
+ return (+hour === 1 ? "la " : "las ") + hour;
458
+ }
459
+ function explicitTimePhrase(hour, minute, opts) {
460
+ if (!opts.ampm) {
461
+ const article = +hour === 1 ? "la " : "las ";
462
+ const suffix = opts.style.hSuffix ? " h" : "";
463
+ return article + clockDigits(
464
+ { hour, minute, second: 0 },
465
+ { pad: true, sep: opts.style.sep }
466
+ ) + suffix;
467
+ }
468
+ const display = hour % 12 || 12;
469
+ const time = (display === 1 ? "la " : "las ") + clockDigits({ hour: display, minute, second: 0 }, { sep: opts.style.sep });
470
+ const period = opts.style.meridiem === "english" ? meridiemMark(hour) : dayPeriod(hour, opts);
471
+ return time + " " + period;
472
+ }
423
473
  function groupClockTimes(phrases) {
424
474
  if (phrases.length < 2) {
425
475
  return joinList(phrases);
@@ -600,13 +650,7 @@ function stepCycle60(segment, unit, anchor, opts) {
600
650
  }
601
651
  return "cada " + numero(interval, opts) + " " + unit + "s a partir del " + unit + " " + start + " de cada " + anchor;
602
652
  }
603
- if (60 % interval === 0) {
604
- return "cada " + numero(interval, opts) + " " + unit + "s";
605
- }
606
- if (segment.fires.length <= 2) {
607
- return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
608
- }
609
- return "cada " + numero(interval, opts) + " " + unit + "s de cada " + anchor;
653
+ return "cada " + numero(interval, opts) + " " + unit + "s";
610
654
  }
611
655
  function stepHours(segment, opts) {
612
656
  if (segment.startToken.indexOf("-") !== -1) {
@@ -614,15 +658,12 @@ function stepHours(segment, opts) {
614
658
  }
615
659
  const start = segment.startToken === "*" ? 0 : +segment.startToken;
616
660
  const interval = segment.interval;
617
- if (start === 0 && 24 % interval === 0) {
661
+ if (start === 0) {
618
662
  return "cada " + numero(interval, opts) + " horas";
619
663
  }
620
664
  if (segment.fires.length <= 3) {
621
665
  return groupClockTimesByArticle(atTimes(segment.fires, opts));
622
666
  }
623
- if (start === 0) {
624
- return "cada " + numero(interval, opts) + " horas desde medianoche";
625
- }
626
667
  return "cada " + numero(interval, opts) + " horas a partir de " + timePhrase(start, 0, null, opts);
627
668
  }
628
669
  function atTimes(hours, opts) {
@@ -1001,17 +1042,15 @@ function numero(n, opts) {
1001
1042
  return numeral(n, numeros, opts);
1002
1043
  }
1003
1044
  function weekdayName(token) {
1004
- if (token === "7" || token === 7) {
1005
- return weekdayNames[0];
1006
- }
1007
- return weekdayNames[token] || weekdayNames[weekdayTokens[token]];
1045
+ const number = toFieldNumber("" + token, weekdayNumbers);
1046
+ return weekdayNames[number === 7 ? 0 : number];
1008
1047
  }
1009
1048
  function pluralWeekday(token) {
1010
1049
  const name = weekdayName(token);
1011
1050
  return name.endsWith("s") ? name : name + "s";
1012
1051
  }
1013
1052
  function monthName(token) {
1014
- return monthNames[token] || monthNames[monthTokens[token]];
1053
+ return monthNames[+token];
1015
1054
  }
1016
1055
  function isOpenStep(field) {
1017
1056
  return field.indexOf("/") !== -1 && field.indexOf("-") === -1 && field.indexOf(",") === -1;
@@ -1021,7 +1060,9 @@ var es2 = {
1021
1060
  fallback: "un patr\xF3n cron irreconocible",
1022
1061
  options: normalizeOptions,
1023
1062
  reboot: "al arrancar el sistema",
1024
- sentence: (description) => "Se ejecuta " + description + "."
1063
+ // A description ending in a period already carries it, so closing the
1064
+ // sentence must not double it.
1065
+ sentence: (description) => "Se ejecuta " + description + (description.endsWith(".") ? "" : ".")
1025
1066
  };
1026
1067
  var index_default = es2;
1027
1068
  module.exports = module.exports.default;