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/CHANGELOG.md +53 -0
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +286 -45
- package/dist/cronli5.js +286 -45
- package/dist/lang/de.cjs +252 -13
- package/dist/lang/de.js +252 -13
- package/dist/lang/en.cjs +281 -38
- package/dist/lang/en.js +281 -38
- package/dist/lang/es.cjs +259 -29
- package/dist/lang/es.js +259 -29
- package/dist/lang/fi.cjs +285 -49
- package/dist/lang/fi.js +285 -49
- package/dist/lang/zh.cjs +225 -42
- package/dist/lang/zh.js +225 -42
- package/package.json +3 -2
- package/src/core/analyze.ts +7 -0
- package/src/core/ir.ts +1 -1
- package/src/core/util.ts +31 -1
- package/src/lang/de/index.ts +561 -30
- package/src/lang/en/index.ts +593 -59
- package/src/lang/es/index.ts +576 -52
- package/src/lang/fi/index.ts +633 -95
- package/src/lang/zh/index.ts +484 -77
- package/types/core/ir.d.ts +1 -1
- package/types/core/util.d.ts +6 -1
package/dist/lang/es.js
CHANGED
|
@@ -24,12 +24,28 @@ var weekdayNumbers = {
|
|
|
24
24
|
FRI: 5,
|
|
25
25
|
SAT: 6
|
|
26
26
|
};
|
|
27
|
+
var maxClockTimes = 6;
|
|
27
28
|
|
|
28
29
|
// src/core/util.ts
|
|
29
30
|
function isNonNegativeInteger(value) {
|
|
30
31
|
const digits = /^\d+$/;
|
|
31
32
|
return digits.test(value);
|
|
32
33
|
}
|
|
34
|
+
function arithmeticStep(values) {
|
|
35
|
+
if (values.length < 5) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const interval = values[1] - values[0];
|
|
39
|
+
if (interval < 2) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
43
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { start: values[0], interval, last: values[values.length - 1] };
|
|
48
|
+
}
|
|
33
49
|
function toFieldNumber(token, numberMap) {
|
|
34
50
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
35
51
|
}
|
|
@@ -147,19 +163,38 @@ function renderSecondsWithinMinute(ir, plan, opts) {
|
|
|
147
163
|
}
|
|
148
164
|
return secondsLeadClause(ir, opts) + ", en el minuto " + minuteField + " de cada hora" + trailingQualifier(ir, opts);
|
|
149
165
|
}
|
|
166
|
+
function secondsListAtClock(ir, rest, opts) {
|
|
167
|
+
const clockPhrases = rest.times.map(function clock(time) {
|
|
168
|
+
return atTime(timePhrase(time.hour, time.minute, null, opts));
|
|
169
|
+
});
|
|
170
|
+
const grouped = groupClockTimesByArticle(clockPhrases);
|
|
171
|
+
const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
|
|
172
|
+
const stride = strideFromSegments(fieldSegments(ir, "second"), "segundo", "", opts);
|
|
173
|
+
const secondsPhrase = stride ?? "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second")));
|
|
174
|
+
const dayFrame = trailingQualifier(ir, opts);
|
|
175
|
+
return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
|
|
176
|
+
}
|
|
177
|
+
function composeHourCadence(ir, plan, opts) {
|
|
178
|
+
const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
|
|
179
|
+
if (!clockRest || ir.shapes.minute !== "single") {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
const minute = +ir.pattern.minute;
|
|
183
|
+
return hourCadence(ir, minute, opts) ?? hourRangeCadence(ir, minute, opts);
|
|
184
|
+
}
|
|
185
|
+
function isPinnedMinuteSeconds(ir, plan) {
|
|
186
|
+
return plan.rest.kind === "clockTimes" && (ir.shapes.second === "wildcard" || ir.shapes.second === "step");
|
|
187
|
+
}
|
|
150
188
|
function renderComposeSeconds(ir, plan, opts) {
|
|
151
|
-
|
|
189
|
+
const hourCad = composeHourCadence(ir, plan, opts);
|
|
190
|
+
if (hourCad !== null) {
|
|
191
|
+
return hourCad;
|
|
192
|
+
}
|
|
193
|
+
if (isPinnedMinuteSeconds(ir, plan)) {
|
|
152
194
|
return pinnedMinuteSeconds(ir, plan.rest, opts);
|
|
153
195
|
}
|
|
154
196
|
if (plan.rest.kind === "clockTimes" && ir.shapes.second === "list") {
|
|
155
|
-
|
|
156
|
-
return atTime(timePhrase(time.hour, time.minute, null, opts));
|
|
157
|
-
});
|
|
158
|
-
const grouped = groupClockTimesByArticle(clockPhrases);
|
|
159
|
-
const clockList = grouped.startsWith("a ") ? grouped.slice(2) : grouped;
|
|
160
|
-
const secondsPhrase = "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second")));
|
|
161
|
-
const dayFrame = trailingQualifier(ir, opts);
|
|
162
|
-
return (dayFrame ? dayFrame.trimStart() + ", " : "") + secondsPhrase + " de " + clockList;
|
|
197
|
+
return secondsListAtClock(ir, plan.rest, opts);
|
|
163
198
|
}
|
|
164
199
|
if (plan.rest.kind === "hourRange" && ir.shapes.second === "step" && ir.pattern.weekday !== "*") {
|
|
165
200
|
const restNode = plan.rest;
|
|
@@ -168,17 +203,32 @@ function renderComposeSeconds(ir, plan, opts) {
|
|
|
168
203
|
const cadence = "cada " + numero(stepSegment(ir.analyses.segments.second).interval, opts) + " segundos del minuto " + ir.pattern.minute;
|
|
169
204
|
return dayFrame + ", " + window + ", " + cadence;
|
|
170
205
|
}
|
|
171
|
-
|
|
206
|
+
if (isEveryOtherMinuteSeconds(ir, plan)) {
|
|
207
|
+
return secondsLeadClause(ir, opts) + " de " + render(ir, plan.rest, opts);
|
|
208
|
+
}
|
|
209
|
+
const restOwnsLead = plan.rest.kind === "compactClockTimes" && ir.analyses.clockSecond;
|
|
210
|
+
const lead = restOwnsLead ? "" : secondsLeadClause(ir, opts) + ", ";
|
|
211
|
+
return lead + render(ir, plan.rest, opts);
|
|
212
|
+
}
|
|
213
|
+
function isEveryOtherMinuteSeconds(ir, plan) {
|
|
214
|
+
if (plan.rest.kind !== "minuteFrequency" || ir.shapes.second !== "wildcard" || ir.shapes.hour !== "wildcard") {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
const minuteStep = stepSegment(ir.analyses.segments.minute);
|
|
218
|
+
return minuteStep.startToken === "*" && minuteStep.interval === 2;
|
|
172
219
|
}
|
|
173
220
|
function pinnedMinuteSeconds(ir, rest, opts) {
|
|
174
221
|
const dayTrail = leadingQualifier(ir, opts).trimEnd();
|
|
175
222
|
const trail = dayTrail ? ", " + dayTrail : "";
|
|
176
|
-
if (+rest.times[0].minute === 0) {
|
|
223
|
+
if (+rest.times[0].minute === 0 && ir.shapes.minute === "single") {
|
|
177
224
|
return secondsLeadClause(ir, opts) + " durante un minuto " + durationHourList(rest.times, opts) + trail;
|
|
178
225
|
}
|
|
179
226
|
return secondsLeadClause(ir, opts) + " de " + explicitClockList(rest.times, opts) + trail;
|
|
180
227
|
}
|
|
181
228
|
function secondsLeadClause(ir, opts) {
|
|
229
|
+
return secondsClause(ir, "minuto", opts);
|
|
230
|
+
}
|
|
231
|
+
function secondsClause(ir, anchor, opts) {
|
|
182
232
|
const secondField = ir.pattern.second;
|
|
183
233
|
const shape = ir.shapes.second;
|
|
184
234
|
if (secondField === "*") {
|
|
@@ -188,18 +238,23 @@ function secondsLeadClause(ir, opts) {
|
|
|
188
238
|
return stepCycle60(
|
|
189
239
|
stepSegment(ir.analyses.segments.second),
|
|
190
240
|
"segundo",
|
|
191
|
-
|
|
241
|
+
anchor,
|
|
192
242
|
opts
|
|
193
243
|
);
|
|
194
244
|
}
|
|
195
245
|
if (shape === "range") {
|
|
196
246
|
const bounds = secondField.split("-");
|
|
197
|
-
return "cada segundo del " + bounds[0] + " al " + bounds[1] + " de cada
|
|
247
|
+
return "cada segundo del " + bounds[0] + " al " + bounds[1] + " de cada " + anchor;
|
|
198
248
|
}
|
|
199
249
|
if (shape === "single") {
|
|
200
|
-
return "en el segundo " + secondField + " de cada
|
|
250
|
+
return "en el segundo " + secondField + " de cada " + anchor;
|
|
201
251
|
}
|
|
202
|
-
return
|
|
252
|
+
return strideFromSegments(
|
|
253
|
+
fieldSegments(ir, "second"),
|
|
254
|
+
"segundo",
|
|
255
|
+
anchor,
|
|
256
|
+
opts
|
|
257
|
+
) ?? "en los segundos " + joinList(segmentWords(fieldSegments(ir, "second"))) + " de cada " + anchor;
|
|
203
258
|
}
|
|
204
259
|
function renderEveryMinute(ir, plan, opts) {
|
|
205
260
|
return "cada minuto" + trailingQualifier(ir, opts);
|
|
@@ -211,10 +266,15 @@ function renderRangeOfMinutes(ir, plan, opts) {
|
|
|
211
266
|
return minuteRangeLead(ir.pattern.minute) + " de cada hora" + trailingQualifier(ir, opts);
|
|
212
267
|
}
|
|
213
268
|
function renderMultipleMinutes(ir, plan, opts) {
|
|
214
|
-
return minutesList(ir) + trailingQualifier(ir, opts);
|
|
269
|
+
return minutesList(ir, opts) + trailingQualifier(ir, opts);
|
|
215
270
|
}
|
|
216
|
-
function minutesList(ir) {
|
|
217
|
-
return
|
|
271
|
+
function minutesList(ir, opts) {
|
|
272
|
+
return strideFromSegments(
|
|
273
|
+
fieldSegments(ir, "minute"),
|
|
274
|
+
"minuto",
|
|
275
|
+
"hora",
|
|
276
|
+
opts
|
|
277
|
+
) ?? "en los minutos " + joinList(segmentWords(fieldSegments(ir, "minute"))) + " de cada hora";
|
|
218
278
|
}
|
|
219
279
|
function minuteRangeLead(minuteField) {
|
|
220
280
|
const bounds = minuteField.split("-");
|
|
@@ -277,7 +337,12 @@ function renderMinuteFrequency(ir, plan, opts) {
|
|
|
277
337
|
opts
|
|
278
338
|
);
|
|
279
339
|
if (plan.hours.kind === "during") {
|
|
280
|
-
|
|
340
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
341
|
+
if (cadence) {
|
|
342
|
+
phrase += ", " + cadence;
|
|
343
|
+
} else {
|
|
344
|
+
phrase += singleHourStep(ir.analyses.segments.hour) ? ", " + stepHourSpan(stepSegment(ir.analyses.segments.hour), opts) : " " + hourSpanFromTimes(ir, plan.hours.times, opts);
|
|
345
|
+
}
|
|
281
346
|
} else if (plan.hours.kind === "window") {
|
|
282
347
|
phrase += " " + hourWindow(plan.hours, opts);
|
|
283
348
|
} else if (plan.hours.kind === "step") {
|
|
@@ -296,21 +361,30 @@ function renderMinuteSpanInHour(ir, plan, opts) {
|
|
|
296
361
|
) + trailingQualifier(ir, opts);
|
|
297
362
|
}
|
|
298
363
|
function renderMinutesAcrossHours(ir, plan, opts) {
|
|
364
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
299
365
|
if (plan.form === "wildcard") {
|
|
366
|
+
if (cadence !== null) {
|
|
367
|
+
return "cada minuto, " + cadence + trailingQualifier(ir, opts);
|
|
368
|
+
}
|
|
300
369
|
if (singleHourStep(ir.analyses.segments.hour)) {
|
|
301
370
|
return "cada minuto, " + stepHourSpan(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
|
|
302
371
|
}
|
|
303
372
|
return "cada minuto " + hourSpanFromTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
304
373
|
}
|
|
305
|
-
const lead = plan.form === "range" ? minuteRangeLead(ir.pattern.minute) : minutesList(ir);
|
|
374
|
+
const lead = plan.form === "range" ? minuteRangeLead(ir.pattern.minute) : minutesList(ir, opts);
|
|
375
|
+
if (cadence !== null) {
|
|
376
|
+
return lead + ", " + cadence + trailingQualifier(ir, opts);
|
|
377
|
+
}
|
|
306
378
|
return lead + ", " + atHourTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
307
379
|
}
|
|
308
380
|
function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
309
381
|
const segment = stepSegment(ir.analyses.segments.hour);
|
|
382
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
310
383
|
if (plan.form === "wildcard") {
|
|
311
384
|
return "cada minuto, " + stepHourSpan(segment, opts) + trailingQualifier(ir, opts);
|
|
312
385
|
}
|
|
313
|
-
|
|
386
|
+
const lead = plan.form === "list" ? minutesList(ir, opts) : minuteRangeLead(ir.pattern.minute);
|
|
387
|
+
return lead + ", " + (cadence ?? stepHours(segment, opts)) + trailingQualifier(ir, opts);
|
|
314
388
|
}
|
|
315
389
|
function renderEveryHour(ir, plan, opts) {
|
|
316
390
|
return "cada hora" + trailingQualifier(ir, opts);
|
|
@@ -326,10 +400,14 @@ function renderHourRange(ir, plan, opts) {
|
|
|
326
400
|
if (ir.pattern.minute === "0") {
|
|
327
401
|
return "cada hora " + window + trailingQualifier(ir, opts);
|
|
328
402
|
}
|
|
329
|
-
const lead = ir.shapes.minute === "single" ? "en el minuto " + ir.pattern.minute + " de cada hora" : minutesList(ir);
|
|
403
|
+
const lead = ir.shapes.minute === "single" ? "en el minuto " + ir.pattern.minute + " de cada hora" : minutesList(ir, opts);
|
|
330
404
|
return lead + ", " + window + trailingQualifier(ir, opts);
|
|
331
405
|
}
|
|
332
406
|
function renderHourStep(ir, plan, opts) {
|
|
407
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
408
|
+
if (cadence !== null) {
|
|
409
|
+
return cadence + trailingQualifier(ir, opts);
|
|
410
|
+
}
|
|
333
411
|
return stepHours(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
|
|
334
412
|
}
|
|
335
413
|
function boundedWindow(plan) {
|
|
@@ -400,6 +478,13 @@ function unionYaseaSuffix(ir, opts) {
|
|
|
400
478
|
return ", ya sea " + domArm(ir, opts) + " o " + dowArm(ir);
|
|
401
479
|
}
|
|
402
480
|
function renderClockTimes(ir, plan, opts) {
|
|
481
|
+
if (ir.shapes.minute === "single") {
|
|
482
|
+
const minute = +ir.pattern.minute;
|
|
483
|
+
const cadence = hourCadence(ir, minute, opts) ?? hourRangeCadence(ir, minute, opts);
|
|
484
|
+
if (cadence !== null) {
|
|
485
|
+
return cadence;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
403
488
|
const phrases = plan.times.map(function clock(time) {
|
|
404
489
|
return atTime(timePhrase(time.hour, time.minute, time.second, opts));
|
|
405
490
|
});
|
|
@@ -581,6 +666,10 @@ function groupClockTimesByArticle(phrases) {
|
|
|
581
666
|
}
|
|
582
667
|
function renderCompactClockTimes(ir, plan, opts) {
|
|
583
668
|
if (plan.fold) {
|
|
669
|
+
const cadence2 = hourCadence(ir, plan.minute, opts) ?? hourRangeCadence(ir, plan.minute, opts);
|
|
670
|
+
if (cadence2 !== null) {
|
|
671
|
+
return cadence2;
|
|
672
|
+
}
|
|
584
673
|
const ranged = hourSegments(ir).some(function range(segment) {
|
|
585
674
|
return segment.kind === "range";
|
|
586
675
|
});
|
|
@@ -589,7 +678,8 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
589
678
|
}
|
|
590
679
|
return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
|
|
591
680
|
}
|
|
592
|
-
const
|
|
681
|
+
const cadence = unevenHourCadence(ir, opts);
|
|
682
|
+
const phrase = cadence ? minutesList(ir, opts) + ", " + cadence + trailingQualifier(ir, opts) : minutesList(ir, opts) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
593
683
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
|
|
594
684
|
}
|
|
595
685
|
var renderers = {
|
|
@@ -612,19 +702,50 @@ var renderers = {
|
|
|
612
702
|
singleMinute: renderSingleMinute,
|
|
613
703
|
standaloneSeconds: renderStandaloneSeconds
|
|
614
704
|
};
|
|
705
|
+
function renderStride(stride, opts) {
|
|
706
|
+
const { interval, start, last, cycle, unit, anchor } = stride;
|
|
707
|
+
const cadence = "cada " + numero(interval, opts) + " " + unit + "s";
|
|
708
|
+
const tiles = cycle % interval === 0;
|
|
709
|
+
if (start === 0 && tiles) {
|
|
710
|
+
return cadence;
|
|
711
|
+
}
|
|
712
|
+
const tail = anchor ? " de cada " + anchor : "";
|
|
713
|
+
if (start < interval && tiles) {
|
|
714
|
+
return cadence + " a partir del " + unit + " " + start + tail;
|
|
715
|
+
}
|
|
716
|
+
return cadence + " del " + unit + " " + start + " al " + last + tail;
|
|
717
|
+
}
|
|
615
718
|
function stepCycle60(segment, unit, anchor, opts) {
|
|
616
719
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
617
720
|
return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
|
|
618
721
|
}
|
|
619
722
|
const start = segment.startToken === "*" ? 0 : +segment.startToken;
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
723
|
+
if (start !== 0 && segment.fires.length <= 3) {
|
|
724
|
+
return "en los " + unit + "s " + joinList(wordList(segment.fires)) + " de cada " + anchor;
|
|
725
|
+
}
|
|
726
|
+
return renderStride({
|
|
727
|
+
interval: segment.interval,
|
|
728
|
+
start,
|
|
729
|
+
last: segment.fires[segment.fires.length - 1],
|
|
730
|
+
cycle: 60,
|
|
731
|
+
unit,
|
|
732
|
+
anchor
|
|
733
|
+
}, opts);
|
|
734
|
+
}
|
|
735
|
+
function strideFromSegments(segments, unit, anchor, opts) {
|
|
736
|
+
const values = singleValues(segments);
|
|
737
|
+
const step = values && arithmeticStep(values);
|
|
738
|
+
return step ? renderStride({ ...step, cycle: 60, unit, anchor }, opts) : null;
|
|
739
|
+
}
|
|
740
|
+
function singleValues(segments) {
|
|
741
|
+
const values = [];
|
|
742
|
+
for (const segment of segments) {
|
|
743
|
+
if (segment.kind !== "single") {
|
|
744
|
+
return null;
|
|
624
745
|
}
|
|
625
|
-
|
|
746
|
+
values.push(+segment.value);
|
|
626
747
|
}
|
|
627
|
-
return
|
|
748
|
+
return values;
|
|
628
749
|
}
|
|
629
750
|
function stepHours(segment, opts) {
|
|
630
751
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
@@ -640,6 +761,115 @@ function stepHours(segment, opts) {
|
|
|
640
761
|
}
|
|
641
762
|
return "cada " + numero(interval, opts) + " horas a partir de " + timePhrase(start, 0, null, opts);
|
|
642
763
|
}
|
|
764
|
+
function hourStrideCadence(stride, opts) {
|
|
765
|
+
const { start, interval, last } = stride;
|
|
766
|
+
const cadence = "cada " + numero(interval, opts) + " horas";
|
|
767
|
+
const tiles = 24 % interval === 0;
|
|
768
|
+
if (start === 0 && tiles) {
|
|
769
|
+
return cadence;
|
|
770
|
+
}
|
|
771
|
+
if (start < interval && tiles) {
|
|
772
|
+
return cadence + " a partir de " + timePhrase(start, 0, null, opts);
|
|
773
|
+
}
|
|
774
|
+
return cadence + " de " + timePhrase(start, 0, null, opts) + " a " + timePhrase(last, 0, null, opts);
|
|
775
|
+
}
|
|
776
|
+
function offsetCleanStride(stride) {
|
|
777
|
+
return stride.start < stride.interval && 24 % stride.interval === 0;
|
|
778
|
+
}
|
|
779
|
+
function unevenHourCadence(ir, opts) {
|
|
780
|
+
const stride = hourStride(ir);
|
|
781
|
+
if (!stride || offsetCleanStride(stride)) {
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
return hourStrideCadence(stride, opts);
|
|
785
|
+
}
|
|
786
|
+
function hourListStride(values) {
|
|
787
|
+
if (values.length < 2) {
|
|
788
|
+
return null;
|
|
789
|
+
}
|
|
790
|
+
const interval = values[1] - values[0];
|
|
791
|
+
if (interval < 2) {
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
794
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
795
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
if (values[0] !== 0 && values.length < 5) {
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
return { interval, last: values[values.length - 1], start: values[0] };
|
|
803
|
+
}
|
|
804
|
+
function hourStride(ir) {
|
|
805
|
+
const segments = fieldSegments(ir, "hour");
|
|
806
|
+
if (segments.length === 1 && segments[0].kind === "step") {
|
|
807
|
+
const segment = segments[0];
|
|
808
|
+
if (segment.fires.length < 2) {
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
|
|
812
|
+
return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
|
|
813
|
+
}
|
|
814
|
+
const values = singleValues(segments);
|
|
815
|
+
return values && hourListStride(values);
|
|
816
|
+
}
|
|
817
|
+
function subMinuteSecond(ir) {
|
|
818
|
+
return ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
819
|
+
}
|
|
820
|
+
function hourCadenceLead(ir, minute, opts) {
|
|
821
|
+
if (minute === 0) {
|
|
822
|
+
if (subMinuteSecond(ir)) {
|
|
823
|
+
return secondsClause(ir, "minuto", opts) + " durante un minuto";
|
|
824
|
+
}
|
|
825
|
+
return secondsClause(ir, "hora", opts);
|
|
826
|
+
}
|
|
827
|
+
const minutePhrase = "en el minuto " + minute;
|
|
828
|
+
if (ir.pattern.second === "0") {
|
|
829
|
+
return minutePhrase;
|
|
830
|
+
}
|
|
831
|
+
return secondsClause(ir, "minuto", opts) + ", " + minutePhrase;
|
|
832
|
+
}
|
|
833
|
+
function hourCadence(ir, minute, opts) {
|
|
834
|
+
const stride = hourStride(ir);
|
|
835
|
+
if (!stride) {
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
839
|
+
if (ir.pattern.second === "0" && fires <= maxClockTimes && offsetCleanStride(stride)) {
|
|
840
|
+
return null;
|
|
841
|
+
}
|
|
842
|
+
const confinement = minute === 0 && subMinuteSecond(ir) && cleanStrideSegment(ir);
|
|
843
|
+
if (confinement) {
|
|
844
|
+
return secondsClause(ir, "minuto", opts) + " durante un minuto, " + stepHourSpan(confinement, opts) + trailingQualifier(ir, opts);
|
|
845
|
+
}
|
|
846
|
+
if (minute === 0 && ir.pattern.second === "0") {
|
|
847
|
+
return hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
|
|
848
|
+
}
|
|
849
|
+
return hourCadenceLead(ir, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
|
|
850
|
+
}
|
|
851
|
+
function cleanStrideSegment(ir) {
|
|
852
|
+
const segments = fieldSegments(ir, "hour");
|
|
853
|
+
const segment = segments.length === 1 && segments[0];
|
|
854
|
+
if (!segment || segment.kind !== "step" || segment.startToken.indexOf("-") !== -1) {
|
|
855
|
+
return null;
|
|
856
|
+
}
|
|
857
|
+
return segment;
|
|
858
|
+
}
|
|
859
|
+
function hasHourWindow(ir) {
|
|
860
|
+
return hourSegments(ir).some(function range(segment) {
|
|
861
|
+
return segment.kind === "range";
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
function hourRangeCadence(ir, minute, opts) {
|
|
865
|
+
if (minute !== 0 || !hasHourWindow(ir) || ir.pattern.second === "0") {
|
|
866
|
+
return null;
|
|
867
|
+
}
|
|
868
|
+
if (subMinuteSecond(ir)) {
|
|
869
|
+
return secondsClause(ir, "minuto", opts) + " durante un minuto, durante las horas " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
870
|
+
}
|
|
871
|
+
return hourCadenceLead(ir, minute, opts) + ", " + hourSegmentTimes(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
872
|
+
}
|
|
643
873
|
function atTimes(hours, opts) {
|
|
644
874
|
return hours.map(function each(hour) {
|
|
645
875
|
return atTime(timePhrase(hour, 0, null, opts));
|