cronli5 0.1.4 → 0.1.5
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 +25 -0
- package/cronli5.min.js +2 -2
- package/dist/cronli5.cjs +180 -36
- package/dist/cronli5.js +180 -36
- package/dist/lang/de.cjs +172 -8
- package/dist/lang/de.js +172 -8
- package/dist/lang/en.cjs +175 -29
- package/dist/lang/en.js +175 -29
- package/dist/lang/es.cjs +180 -25
- package/dist/lang/es.js +180 -25
- package/dist/lang/fi.cjs +188 -40
- package/dist/lang/fi.js +188 -40
- package/dist/lang/zh.cjs +165 -19
- package/dist/lang/zh.js +165 -19
- package/package.json +2 -1
- 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 +360 -16
- package/src/lang/en/index.ts +333 -33
- package/src/lang/es/index.ts +373 -40
- package/src/lang/fi/index.ts +404 -72
- package/src/lang/zh/index.ts +327 -35
- package/types/core/ir.d.ts +1 -1
- package/types/core/util.d.ts +6 -1
package/dist/lang/fi.cjs
CHANGED
|
@@ -50,12 +50,28 @@ var weekdayNumbers = {
|
|
|
50
50
|
FRI: 5,
|
|
51
51
|
SAT: 6
|
|
52
52
|
};
|
|
53
|
+
var maxClockTimes = 6;
|
|
53
54
|
|
|
54
55
|
// src/core/util.ts
|
|
55
56
|
function isNonNegativeInteger(value) {
|
|
56
57
|
const digits = /^\d+$/;
|
|
57
58
|
return digits.test(value);
|
|
58
59
|
}
|
|
60
|
+
function arithmeticStep(values) {
|
|
61
|
+
if (values.length < 5) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const interval = values[1] - values[0];
|
|
65
|
+
if (interval < 2) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
for (let i = 2; i < values.length; i += 1) {
|
|
69
|
+
if (values[i] - values[i - 1] !== interval) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { start: values[0], interval, last: values[values.length - 1] };
|
|
74
|
+
}
|
|
59
75
|
function toFieldNumber(token, numberMap) {
|
|
60
76
|
return isNonNegativeInteger(token) ? +token : numberMap[token.toUpperCase()];
|
|
61
77
|
}
|
|
@@ -191,12 +207,14 @@ var units = {
|
|
|
191
207
|
mark: "joka tunti",
|
|
192
208
|
anchor: "jokaisen tunnin",
|
|
193
209
|
ela: "minuutista",
|
|
210
|
+
ill: "minuuttiin",
|
|
194
211
|
gen: "minuutin"
|
|
195
212
|
},
|
|
196
213
|
second: {
|
|
197
214
|
mark: "joka minuutti",
|
|
198
215
|
anchor: "jokaisen minuutin",
|
|
199
216
|
ela: "sekunnista",
|
|
217
|
+
ill: "sekuntiin",
|
|
200
218
|
gen: "sekunnin"
|
|
201
219
|
}
|
|
202
220
|
};
|
|
@@ -252,29 +270,50 @@ function renderSecondsWithinMinute(ir, plan, opts) {
|
|
|
252
270
|
}
|
|
253
271
|
return secondsLeadClause(ir, opts) + ", " + atMarks(minuteField, units.minute, true) + trailingQualifier(ir, opts);
|
|
254
272
|
}
|
|
273
|
+
function composeSecondsOverMinuteStep(ir, freq, opts) {
|
|
274
|
+
const seg = stepSegment(ir.analyses.segments.minute);
|
|
275
|
+
const stepPhrase = stepCycle60(seg, units.minute, opts);
|
|
276
|
+
if (freq.hours.kind === "during" && minuteStepIsAnchored(seg)) {
|
|
277
|
+
const bareHours = kloFromTimes(ir, freq.hours.times, opts);
|
|
278
|
+
return hoursFirstMinutes(bareHours, ir, opts) + ", " + secondsLeadClause(ir, opts) + trailingQualifier(ir, opts);
|
|
279
|
+
}
|
|
280
|
+
let hourClause = "";
|
|
281
|
+
if (freq.hours.kind === "during") {
|
|
282
|
+
hourClause = " " + hourWindowsFromTimes(ir, freq.hours.times, opts);
|
|
283
|
+
} else if (freq.hours.kind === "window") {
|
|
284
|
+
hourClause = " " + hourWindow(freq.hours, opts);
|
|
285
|
+
} else if (freq.hours.kind === "step") {
|
|
286
|
+
hourClause = " " + everyNthHour(stepSegment(ir.analyses.segments.hour), opts);
|
|
287
|
+
}
|
|
288
|
+
return stepPhrase + ", " + secondsLeadClause(ir, opts) + hourClause + trailingQualifier(ir, opts);
|
|
289
|
+
}
|
|
290
|
+
function composeHourCadence(ir, plan, opts) {
|
|
291
|
+
const clockRest = plan.rest.kind === "clockTimes" || plan.rest.kind === "compactClockTimes";
|
|
292
|
+
return clockRest && ir.shapes.minute === "single" ? hourCadence(ir, +ir.pattern.minute, opts) : null;
|
|
293
|
+
}
|
|
255
294
|
function renderComposeSeconds(ir, plan, opts) {
|
|
295
|
+
const cadence = composeHourCadence(ir, plan, opts);
|
|
296
|
+
if (cadence !== null) {
|
|
297
|
+
return cadence;
|
|
298
|
+
}
|
|
256
299
|
if (plan.rest.kind === "minuteFrequency" && ir.pattern.second !== "*") {
|
|
257
|
-
|
|
258
|
-
const seg = stepSegment(ir.analyses.segments.minute);
|
|
259
|
-
const stepPhrase = stepCycle60(seg, units.minute, opts);
|
|
260
|
-
let hourClause = "";
|
|
261
|
-
if (freq.hours.kind === "during" && minuteStepIsAnchored(seg)) {
|
|
262
|
-
const bareHours = kloFromTimes(ir, freq.hours.times, opts);
|
|
263
|
-
return hoursFirstMinutes(bareHours, ir) + ", " + secondsLeadClause(ir, opts) + trailingQualifier(ir, opts);
|
|
264
|
-
} else if (freq.hours.kind === "during" && !minuteStepIsAnchored(seg)) {
|
|
265
|
-
hourClause = " " + hourWindowsFromTimes(ir, freq.hours.times, opts);
|
|
266
|
-
} else if (freq.hours.kind === "window") {
|
|
267
|
-
hourClause = " " + hourWindow(freq.hours, opts);
|
|
268
|
-
} else if (freq.hours.kind === "step") {
|
|
269
|
-
hourClause = " " + everyNthHour(stepSegment(ir.analyses.segments.hour), opts);
|
|
270
|
-
}
|
|
271
|
-
return stepPhrase + ", " + secondsLeadClause(ir, opts) + hourClause + trailingQualifier(ir, opts);
|
|
300
|
+
return composeSecondsOverMinuteStep(ir, plan.rest, opts);
|
|
272
301
|
}
|
|
273
302
|
if (plan.rest.kind === "clockTimes" && plan.rest.times.every((time) => +time.minute === 0)) {
|
|
274
303
|
return composeMinuteZero(ir, plan.rest, opts);
|
|
275
304
|
}
|
|
305
|
+
if (isEveryOtherMinuteSeconds(ir, plan)) {
|
|
306
|
+
return secondsLeadClause(ir, opts) + " joka toisena minuuttina";
|
|
307
|
+
}
|
|
276
308
|
return secondsLeadClause(ir, opts) + ", " + render(ir, plan.rest, opts);
|
|
277
309
|
}
|
|
310
|
+
function isEveryOtherMinuteSeconds(ir, plan) {
|
|
311
|
+
if (plan.rest.kind !== "minuteFrequency" || ir.pattern.second !== "*" || ir.shapes.hour !== "wildcard") {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
const seg = stepSegment(ir.analyses.segments.minute);
|
|
315
|
+
return seg.startToken === "*" && seg.interval === 2;
|
|
316
|
+
}
|
|
278
317
|
function composeMinuteZero(ir, rest, opts) {
|
|
279
318
|
const clocks = rest.times.map(function clock(time) {
|
|
280
319
|
return clockDigits(
|
|
@@ -303,7 +342,7 @@ function secondsLeadClause(ir, opts) {
|
|
|
303
342
|
if (shape === "single") {
|
|
304
343
|
return atMarks(secondField, units.second, marked);
|
|
305
344
|
}
|
|
306
|
-
return atMarks(
|
|
345
|
+
return strideFromSegments(ir.analyses.segments.second, units.second, opts) ?? atMarks(
|
|
307
346
|
joinList(segmentWords(ir.analyses.segments.second)),
|
|
308
347
|
units.second,
|
|
309
348
|
marked
|
|
@@ -316,20 +355,20 @@ function renderSingleMinute(ir, plan, opts) {
|
|
|
316
355
|
return atMarks(ir.pattern.minute, units.minute, true) + trailingQualifier(ir, opts);
|
|
317
356
|
}
|
|
318
357
|
function renderRangeOfMinutes(ir, plan, opts) {
|
|
319
|
-
return minutesList(ir) + trailingQualifier(ir, opts);
|
|
358
|
+
return minutesList(ir, opts) + trailingQualifier(ir, opts);
|
|
320
359
|
}
|
|
321
360
|
function renderMultipleMinutes(ir, plan, opts) {
|
|
322
|
-
return minutesList(ir) + trailingQualifier(ir, opts);
|
|
361
|
+
return minutesList(ir, opts) + trailingQualifier(ir, opts);
|
|
323
362
|
}
|
|
324
|
-
function minutesList(ir) {
|
|
325
|
-
return atMarks(
|
|
363
|
+
function minutesList(ir, opts) {
|
|
364
|
+
return strideFromSegments(ir.analyses.segments.minute, units.minute, opts) ?? atMarks(
|
|
326
365
|
joinList(segmentWords(ir.analyses.segments.minute)),
|
|
327
366
|
units.minute,
|
|
328
367
|
true
|
|
329
368
|
);
|
|
330
369
|
}
|
|
331
|
-
function bareMinutes(ir) {
|
|
332
|
-
return atMarks(
|
|
370
|
+
function bareMinutes(ir, opts) {
|
|
371
|
+
return strideFromSegments(ir.analyses.segments.minute, units.minute, opts) ?? atMarks(
|
|
333
372
|
joinList(segmentWords(ir.analyses.segments.minute)),
|
|
334
373
|
units.minute,
|
|
335
374
|
false
|
|
@@ -360,7 +399,11 @@ function hoursAreRangeIsolated(segments) {
|
|
|
360
399
|
}
|
|
361
400
|
return hasRange && hasSingle;
|
|
362
401
|
}
|
|
363
|
-
function hoursFirstMinutes(hoursStr, ir) {
|
|
402
|
+
function hoursFirstMinutes(hoursStr, ir, opts) {
|
|
403
|
+
const stride = strideFromSegments(ir.analyses.segments.minute, units.minute, opts);
|
|
404
|
+
if (stride) {
|
|
405
|
+
return hoursStr + " aina " + stride;
|
|
406
|
+
}
|
|
364
407
|
return hoursStr + " aina minuuttien " + joinList(segmentWords(ir.analyses.segments.minute)) + " kohdalla";
|
|
365
408
|
}
|
|
366
409
|
function hourSegmentTimesWithSeka(ir, minute, second, opts) {
|
|
@@ -383,7 +426,7 @@ function renderMinuteFrequency(ir, plan, opts) {
|
|
|
383
426
|
if (plan.hours.kind === "during") {
|
|
384
427
|
if (minuteStepIsAnchored(seg)) {
|
|
385
428
|
const bareHours = kloFromTimes(ir, plan.hours.times, opts);
|
|
386
|
-
return hoursFirstMinutes(bareHours, ir) + trailingQualifier(ir, opts);
|
|
429
|
+
return hoursFirstMinutes(bareHours, ir, opts) + trailingQualifier(ir, opts);
|
|
387
430
|
}
|
|
388
431
|
return stepCycle60(seg, units.minute, opts) + " " + hourWindowsFromTimes(ir, plan.hours.times, opts) + trailingQualifier(ir, opts);
|
|
389
432
|
}
|
|
@@ -410,10 +453,10 @@ function renderMinutesAcrossHours(ir, plan, opts) {
|
|
|
410
453
|
return "joka minuutti " + hourWindowsFromTimes(ir, plan.times, opts) + trailingQualifier(ir, opts);
|
|
411
454
|
}
|
|
412
455
|
if (hoursAreRangeIsolated(ir.analyses.segments.hour)) {
|
|
413
|
-
return bareMinutes(ir) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
456
|
+
return bareMinutes(ir, opts) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
414
457
|
}
|
|
415
458
|
const hoursStr = kloFromTimes(ir, plan.times, opts);
|
|
416
|
-
return hoursFirstMinutes(hoursStr, ir) + trailingQualifier(ir, opts);
|
|
459
|
+
return hoursFirstMinutes(hoursStr, ir, opts) + trailingQualifier(ir, opts);
|
|
417
460
|
}
|
|
418
461
|
function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
419
462
|
const segment = stepSegment(ir.analyses.segments.hour);
|
|
@@ -422,9 +465,9 @@ function renderMinuteSpanAcrossHourStep(ir, plan, opts) {
|
|
|
422
465
|
}
|
|
423
466
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
424
467
|
const hoursStr = kloList(segment.fires, opts);
|
|
425
|
-
return hoursFirstMinutes(hoursStr, ir) + trailingQualifier(ir, opts);
|
|
468
|
+
return hoursFirstMinutes(hoursStr, ir, opts) + trailingQualifier(ir, opts);
|
|
426
469
|
}
|
|
427
|
-
return bareMinutes(ir) + hourStepTail(segment, opts) + trailingQualifier(ir, opts);
|
|
470
|
+
return bareMinutes(ir, opts) + hourStepTail(segment, opts) + trailingQualifier(ir, opts);
|
|
428
471
|
}
|
|
429
472
|
function plainHourStep(segment) {
|
|
430
473
|
return segment.startToken === "*" && 24 % segment.interval === 0;
|
|
@@ -482,7 +525,7 @@ function renderHourRange(ir, plan, opts) {
|
|
|
482
525
|
return "joka minuutti " + window + trailingQualifier(ir, opts);
|
|
483
526
|
}
|
|
484
527
|
if (plan.minuteForm === "range") {
|
|
485
|
-
return hoursFirstMinutes(window, ir) + trailingQualifier(ir, opts);
|
|
528
|
+
return hoursFirstMinutes(window, ir, opts) + trailingQualifier(ir, opts);
|
|
486
529
|
}
|
|
487
530
|
if (ir.pattern.minute === "0") {
|
|
488
531
|
return "joka tunti " + window + trailingQualifier(ir, opts);
|
|
@@ -494,7 +537,7 @@ function renderHourRange(ir, plan, opts) {
|
|
|
494
537
|
opts
|
|
495
538
|
) + trailingQualifier(ir, opts);
|
|
496
539
|
}
|
|
497
|
-
return hoursFirstMinutes(window, ir) + trailingQualifier(ir, opts);
|
|
540
|
+
return hoursFirstMinutes(window, ir, opts) + trailingQualifier(ir, opts);
|
|
498
541
|
}
|
|
499
542
|
function renderHourStep(ir, plan, opts) {
|
|
500
543
|
return stepHours(stepSegment(ir.analyses.segments.hour), opts) + trailingQualifier(ir, opts);
|
|
@@ -510,6 +553,12 @@ function hourWindow(window, opts) {
|
|
|
510
553
|
);
|
|
511
554
|
}
|
|
512
555
|
function renderClockTimes(ir, plan, opts) {
|
|
556
|
+
if (ir.shapes.minute === "single") {
|
|
557
|
+
const cadence = hourCadence(ir, +ir.pattern.minute, opts);
|
|
558
|
+
if (cadence !== null) {
|
|
559
|
+
return cadence;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
513
562
|
if (plan.times.length === 1) {
|
|
514
563
|
const time = plan.times[0];
|
|
515
564
|
return leadingQualifier(ir, opts) + timeWord(time.hour, time.minute, time.second, opts);
|
|
@@ -520,6 +569,12 @@ function renderClockTimes(ir, plan, opts) {
|
|
|
520
569
|
return leadingQualifier(ir, opts) + "klo " + joinList(digits);
|
|
521
570
|
}
|
|
522
571
|
function renderCompactClockTimes(ir, plan, opts) {
|
|
572
|
+
if (plan.fold) {
|
|
573
|
+
const cadence = hourCadence(ir, plan.minute, opts);
|
|
574
|
+
if (cadence !== null) {
|
|
575
|
+
return cadence;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
523
578
|
const hourSegs = ir.analyses.segments.hour;
|
|
524
579
|
if (hoursAreRangeIsolated(hourSegs)) {
|
|
525
580
|
if (plan.fold) {
|
|
@@ -530,14 +585,14 @@ function renderCompactClockTimes(ir, plan, opts) {
|
|
|
530
585
|
opts
|
|
531
586
|
);
|
|
532
587
|
}
|
|
533
|
-
const phrase2 = bareMinutes(ir) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
588
|
+
const phrase2 = bareMinutes(ir, opts) + " " + hourSegmentTimesWithSeka(ir, 0, null, opts) + trailingQualifier(ir, opts);
|
|
534
589
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase2 : phrase2;
|
|
535
590
|
}
|
|
536
591
|
if (plan.fold) {
|
|
537
592
|
return leadingQualifier(ir, opts) + hourSegmentTimes(ir, plan.minute, ir.analyses.clockSecond, opts);
|
|
538
593
|
}
|
|
539
594
|
const hoursStr = hourSegmentTimes(ir, 0, null, opts);
|
|
540
|
-
const phrase = hoursFirstMinutes(hoursStr, ir) + trailingQualifier(ir, opts);
|
|
595
|
+
const phrase = hoursFirstMinutes(hoursStr, ir, opts) + trailingQualifier(ir, opts);
|
|
541
596
|
return ir.analyses.clockSecond ? secondsLeadClause(ir, opts) + ", " + phrase : phrase;
|
|
542
597
|
}
|
|
543
598
|
var renderers = {
|
|
@@ -560,20 +615,48 @@ var renderers = {
|
|
|
560
615
|
singleMinute: renderSingleMinute,
|
|
561
616
|
standaloneSeconds: renderStandaloneSeconds
|
|
562
617
|
};
|
|
618
|
+
function renderStride(stride, opts) {
|
|
619
|
+
const { interval, start, last, cycle, unit } = stride;
|
|
620
|
+
const cadence = genitive(interval, opts) + " " + unit.gen + " v\xE4lein";
|
|
621
|
+
const tiles = cycle % interval === 0;
|
|
622
|
+
if (start === 0 && tiles) {
|
|
623
|
+
return cadence;
|
|
624
|
+
}
|
|
625
|
+
if (start < interval && tiles) {
|
|
626
|
+
return cadence + " " + unit.anchor + " " + unit.ela + " " + start + " alkaen";
|
|
627
|
+
}
|
|
628
|
+
return cadence + " " + unit.ela + " " + start + " " + unit.ill + " " + last;
|
|
629
|
+
}
|
|
630
|
+
function strideFromSegments(segments, unit, opts) {
|
|
631
|
+
const values = singleValues(segments);
|
|
632
|
+
const step = values && arithmeticStep(values);
|
|
633
|
+
return step ? renderStride({ ...step, cycle: 60, unit }, opts) : null;
|
|
634
|
+
}
|
|
635
|
+
function singleValues(segments) {
|
|
636
|
+
const values = [];
|
|
637
|
+
for (const segment of segments) {
|
|
638
|
+
if (segment.kind !== "single") {
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
values.push(+segment.value);
|
|
642
|
+
}
|
|
643
|
+
return values;
|
|
644
|
+
}
|
|
563
645
|
function stepCycle60(segment, unit, opts) {
|
|
564
646
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
565
647
|
return atMarks(joinList(wordList(segment.fires)), unit, true);
|
|
566
648
|
}
|
|
567
649
|
const start = segment.startToken === "*" ? 0 : +segment.startToken;
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
if (start !== 0) {
|
|
571
|
-
if (segment.fires.length <= 3) {
|
|
572
|
-
return atMarks(joinList(wordList(segment.fires)), unit, true);
|
|
573
|
-
}
|
|
574
|
-
return cadence + " " + unit.anchor + " " + unit.ela + " " + start + " alkaen";
|
|
650
|
+
if (start !== 0 && segment.fires.length <= 3) {
|
|
651
|
+
return atMarks(joinList(wordList(segment.fires)), unit, true);
|
|
575
652
|
}
|
|
576
|
-
return
|
|
653
|
+
return renderStride({
|
|
654
|
+
interval: segment.interval,
|
|
655
|
+
start,
|
|
656
|
+
last: segment.fires[segment.fires.length - 1],
|
|
657
|
+
cycle: 60,
|
|
658
|
+
unit
|
|
659
|
+
}, opts);
|
|
577
660
|
}
|
|
578
661
|
function stepHours(segment, opts) {
|
|
579
662
|
if (segment.startToken.indexOf("-") !== -1) {
|
|
@@ -590,6 +673,71 @@ function stepHours(segment, opts) {
|
|
|
590
673
|
}
|
|
591
674
|
return cadence + " klo " + hourElatives[start] + " alkaen";
|
|
592
675
|
}
|
|
676
|
+
function hourStrideCadence(stride, opts) {
|
|
677
|
+
const { start, interval, last } = stride;
|
|
678
|
+
const cadence = genitive(interval, opts) + " tunnin v\xE4lein";
|
|
679
|
+
const tiles = 24 % interval === 0;
|
|
680
|
+
if (start === 0 && tiles) {
|
|
681
|
+
return cadence;
|
|
682
|
+
}
|
|
683
|
+
if (start < interval && tiles) {
|
|
684
|
+
return cadence + " klo " + hourElatives[start] + " alkaen";
|
|
685
|
+
}
|
|
686
|
+
return cadence + " " + kloRange({ hour: start, minute: 0 }, { hour: last, minute: 0 }, opts);
|
|
687
|
+
}
|
|
688
|
+
function hourStride(ir) {
|
|
689
|
+
const segments = ir.analyses.segments.hour;
|
|
690
|
+
if (!segments) {
|
|
691
|
+
return null;
|
|
692
|
+
}
|
|
693
|
+
if (segments.length === 1 && segments[0].kind === "step") {
|
|
694
|
+
const segment = segments[0];
|
|
695
|
+
const start = segment.startToken === "*" ? 0 : +segment.startToken.split("-")[0];
|
|
696
|
+
return { interval: segment.interval, last: segment.fires[segment.fires.length - 1], start };
|
|
697
|
+
}
|
|
698
|
+
const values = singleValues(segments);
|
|
699
|
+
const step = values && arithmeticStep(values);
|
|
700
|
+
return step || null;
|
|
701
|
+
}
|
|
702
|
+
function subMinuteSecond(ir) {
|
|
703
|
+
return ir.pattern.second === "*" || ir.shapes.second === "step";
|
|
704
|
+
}
|
|
705
|
+
function hourCadenceLead(ir, minute, opts) {
|
|
706
|
+
if (minute === 0) {
|
|
707
|
+
if (subMinuteSecond(ir)) {
|
|
708
|
+
return secondsLeadClause(ir, opts) + " minuutin ajan";
|
|
709
|
+
}
|
|
710
|
+
return secondsLeadClause(ir, opts);
|
|
711
|
+
}
|
|
712
|
+
const minutePhrase = atMarks(String(minute), units.minute, false);
|
|
713
|
+
if (ir.pattern.second === "0") {
|
|
714
|
+
return minutePhrase;
|
|
715
|
+
}
|
|
716
|
+
return secondsLeadClause(ir, opts) + ", " + minutePhrase;
|
|
717
|
+
}
|
|
718
|
+
function hourCadence(ir, minute, opts) {
|
|
719
|
+
const stride = hourStride(ir);
|
|
720
|
+
if (!stride) {
|
|
721
|
+
return null;
|
|
722
|
+
}
|
|
723
|
+
const fires = (stride.last - stride.start) / stride.interval + 1;
|
|
724
|
+
if (ir.pattern.second === "0" && fires <= maxClockTimes) {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
const segment = ir.analyses.segments.hour[0];
|
|
728
|
+
const confined = minute === 0 && subMinuteSecond(ir) && ir.analyses.segments.hour.length === 1 && segment.kind === "step" && cleanHourStride(segment);
|
|
729
|
+
if (confined) {
|
|
730
|
+
return secondsLeadClause(ir, opts) + " minuutin ajan " + everyNthHour(segment, opts) + trailingQualifier(ir, opts);
|
|
731
|
+
}
|
|
732
|
+
return hourCadenceLead(ir, minute, opts) + ", " + hourStrideCadence(stride, opts) + trailingQualifier(ir, opts);
|
|
733
|
+
}
|
|
734
|
+
function cleanHourStride(segment) {
|
|
735
|
+
if (segment.startToken.indexOf("-") !== -1) {
|
|
736
|
+
return false;
|
|
737
|
+
}
|
|
738
|
+
const start = segment.startToken === "*" ? 0 : +segment.startToken;
|
|
739
|
+
return 24 % segment.interval === 0 && start < segment.interval;
|
|
740
|
+
}
|
|
593
741
|
function kloList(hours, opts) {
|
|
594
742
|
if (hours.length === 1) {
|
|
595
743
|
return timeWord(hours[0], 0, null, opts);
|