fugit 1.12.0 → 1.12.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31f13ce15ee0d51e6029539634fd55e14401f60ba03cdc6ad90c8e47bd4b711e
4
- data.tar.gz: 91db0bb6fd6aa714e44e4c6d2b67fdbffc70495da77bf9946cda8d859bdf510a
3
+ metadata.gz: 15a3ea665c020e35ce51dcbc82be9a74e6f4abcaa2441316b514c630ffdbc094
4
+ data.tar.gz: f99246722de255325b57ea46f7b3f24bbfc11d65f1eb98fde9a2a43a3c249df0
5
5
  SHA512:
6
- metadata.gz: 604a819a90770a746f33f2d93cdab4524f036a71ac901d311fb74c438f20eaa01a4fb13187f5eca96b7a449354d7864ef3b515674088b3bc60b36710afd8c9df
7
- data.tar.gz: c83c544fa51e1a3e8bc2f76ff163276caa61a93927db6bbfe47642d91ffa85281c8522e1b36a2e9c988c85963c34edc86b47fab98dc1ee516a4495df63839ac8
6
+ metadata.gz: cc55e7332f5f111ddf27d145fed7fbfeaeed30f492ba343d1f4067e776c96874b42bad9488b9683203040cc50333f74bab56fa6e61744ef92fb059f2a2c9f076
7
+ data.tar.gz: 5ee65240dd04fddb7777bee327f8fee0cfef5260ed55db9ec71ece64c5e5e6b53283aa7d26ba52facbca3882aee0920ff0dd3715fea5ad9153caca82ea712450
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
  # CHANGELOG.md
3
3
 
4
4
 
5
+ ## fugit 1.12.1 released 2025-10-14
6
+
7
+ * Fix Fugit::Cron#to_cron_s to include & if @day_and
8
+
9
+
5
10
  ## fugit 1.12.0 released 2025-09-30
6
11
 
7
12
  * Upgrade et-orbi to ~> 1.4.0 for EtOrbi.rweek_ref=, gh-114
data/CREDITS.md CHANGED
@@ -1,7 +1,8 @@
1
1
 
2
2
  # fugit credits
3
3
 
4
- * Hugh Kelsey https://github.com/hughkelsey gh-94 rweek/rday / wed%4+1,wed%4
4
+ * Eric Claerhout https://github.com/swebra gh-114 rweek readme clarity
5
+ * Hugh Kelsey https://github.com/hughkelsey gh-114 rweek/rday / wed%4+1,wed%4
5
6
  * Mark R. James, https://github.com/mrj, AM vs America/Los_Angeles, gh-113
6
7
  * Tejas Bubane, https://github.com/tejasbubane, r3.4 in test matrix, gh-109
7
8
  * Luis Castillo, https://github.com/lekastillo, nice_hash gh-108
data/README.md CHANGED
@@ -296,125 +296,187 @@ The hash extension can only be used in the day-of-week field.
296
296
 
297
297
  ### the modulo extension
298
298
 
299
- Fugit, since 1.1.10, also understands cron strings like `9 0 * * sun%2` which can be read as "every other Sunday at 9am" or `12 0 * * mon%4` for "every fourth monday at noon".
299
+ Since 1.1.10, fugit also understands cron strings like `9 0 * * sun%2` which can be read as "every other Sunday at 9am" or `12 0 * * mon%4` for "every fourth monday at noon".
300
300
 
301
301
  The modulo extension can only be used in the day-of-week field.
302
302
 
303
303
  For odd Sundays, one can write `9 0 * * sun%2+1`.
304
304
 
305
- It can be combined, as in `9 0 * * sun%2,tue%3+2`
305
+ It can be combined, as in `9 0 * * sun%2,tue%3+2`, which will match every other Sunday and 1 in 3 Tuesdays (with an offset of 2).
306
306
 
307
- But what does it reference to? It starts at 1 on 2019-01-01 (in the EtOrbi instance timezone, not the UTC "timezone").
308
-
309
- Since [et-orbi](https://github.com/floraison/et-orbi) 1.4.0, the reference has been switched to make `Monday 2018-12-31` as the reference, so that weeks start on Monday (read a bit below on how to make it start on another day).
307
+ What does `sun%2` actually mean?
308
+ ```ruby
309
+ t.wday == 0 && t.rweek % 2 == 0
310
+ ```
310
311
 
312
+ What does `tue%3+2` mean?
311
313
  ```ruby
312
- require 'et-orbi' # >= 1.1.8 and < 1.4.0
314
+ t.wday == 2 && t.rweek % 3 == 2
315
+ ```
313
316
 
314
- class EtOrbi::EoTime
315
- def d # debug
316
- "%14s | rday: %4d | rweek: %3d" % [ strftime('%a'), rday, rweek ]
317
- end
318
- end
317
+ #### et-orbi < 1.4.0 : reference set on Tuesday 2019-01-01
319
318
 
320
- # the reference
321
- puts EtOrbi.parse('2019-01-01').d # => Tue | rday: 1 | rweek: 1
322
- p EtOrbi.parse('2019-01-01').rweek % 2 # => 1
319
+ The original implementation of `#rweek` (and `#rday`) found in [et-orbi](https://github.com/floraison/et-orbi) was initially pointing to "Tuesday 2019-01-01" and it was set as rday 1 and rweek 1.
323
320
 
324
- # today (as of this coding...)
325
- puts EtOrbi.parse('2019-04-11').d # => Thu | rday: 101 | rweek: 15
326
- p EtOrbi.parse('2019-04-11').rweek % 2 # => 1
321
+ Consider this iteration through the days around 2019-01-01.
322
+ ```ruby
323
+ require 'fugit'
327
324
 
328
- c = Fugit.parse('* * * * tue%2')
329
- p c.match?('2019-01-01') # => false, since rweek % 2 == 1
330
- p c.match?('2019-01-08') # => true, since rweek % 2 == 0
325
+ t = EtOrbi.parse('2018-12-28 12:00')
331
326
 
332
- c = Fugit.parse('* * * * tue%2+1')
333
- p c.match?('2019-01-01') # => true, since (rweek + 1) % 2 == 0
334
- p c.match?('2019-01-08') # => false, since (rweek + 1) % 2 == 1
327
+ 15.times do |i|
335
328
 
336
- # ...
329
+ puts " * %14s / rday: %5d / rweek: %5d" % [
330
+ t.strftime('%F %a'), t.rday, t.rweek ]
337
331
 
338
- class EtOrbi::EoTime
339
- def d # debug
340
- "%14s | rday: %4d | rweek: %3d" % [ strftime('%F %a'), rday, rweek ]
332
+ w = t.rweek
333
+ t = t.add(24 * 3600)
334
+ puts if t.rweek != w
335
+
336
+ if i == 7
337
+ puts "\n (...)\n\n"
338
+ t = EtOrbi.parse('2025-10-04 12:00')
341
339
  end
342
340
  end
341
+ ```
343
342
 
344
- c = Fugit.parse_cron('20 0 * * mon%2,wed%3+1')
345
- puts c.next('2025-09-21').take(10).map(&:d)
346
- #
347
- # => 2025-09-24 Wed | rday: 2459 | rweek: 352
348
- # 2025-09-29 Mon | rday: 2464 | rweek: 352
349
- # 2025-10-13 Mon | rday: 2478 | rweek: 354
350
- # 2025-10-15 Wed | rday: 2480 | rweek: 355
351
- # 2025-10-27 Mon | rday: 2492 | rweek: 356
352
- # 2025-11-05 Wed | rday: 2501 | rweek: 358
353
- # 2025-11-10 Mon | rday: 2506 | rweek: 358
354
- # 2025-11-24 Mon | rday: 2520 | rweek: 360
355
- # 2025-11-26 Wed | rday: 2522 | rweek: 361
356
- # 2025-12-08 Mon | rday: 2534 | rweek: 362
357
- ```
358
-
359
- `sun%2` matches if Sunday and `current_date.rweek % 2 == 0`
360
- `tue%3+2` matches if Tuesday and `current_date.rweek + 2 % 3 == 0`
361
- `tue%x+y` matches if Tuesday and `current_date.rweek + y % x == 0`
343
+ For et-orbi 1.2.11, it yields:
344
+ ```
345
+ * 2018-12-28 Fri / rday: -3 / rweek: 0
346
+ * 2018-12-29 Sat / rday: -2 / rweek: 0
347
+ * 2018-12-30 Sun / rday: -1 / rweek: 0
348
+ * 2018-12-31 Mon / rday: 0 / rweek: 0
349
+
350
+ * 2019-01-01 Tue / rday: 1 / rweek: 1
351
+ * 2019-01-02 Wed / rday: 2 / rweek: 1
352
+ * 2019-01-03 Thu / rday: 3 / rweek: 1
353
+ * 2019-01-04 Fri / rday: 4 / rweek: 1
354
+ * 2019-01-05 Sat / rday: 5 / rweek: 1
355
+
356
+ (...)
357
+
358
+ * 2025-10-04 Sat / rday: 2469 / rweek: 353
359
+ * 2025-10-05 Sun / rday: 2470 / rweek: 353
360
+ * 2025-10-06 Mon / rday: 2471 / rweek: 353
361
+
362
+ * 2025-10-07 Tue / rday: 2472 / rweek: 354
363
+ * 2025-10-08 Wed / rday: 2473 / rweek: 354
364
+ * 2025-10-09 Thu / rday: 2474 / rweek: 354
365
+ ```
362
366
 
363
- ```ruby
364
- require 'et-orbi' # >= 1.4.0
367
+ This [was problematic](https://github.com/floraison/fugit/issues/114), since the week started on, well, Tuesday.
365
368
 
366
- class EtOrbi::EoTime
367
- def d # debug
368
- "%14s | rday: %4d | rweek: %3d" % [ strftime('%a'), rday, rweek ]
369
- end
370
- end
371
369
 
372
- puts EtOrbi.parse('2018-12-30').d # => Sun | rday: -1 | rweek: -1
373
- puts EtOrbi.parse('2018-12-31').d # => Mon | rday: 0 | rweek: 0 >REF<
374
- puts EtOrbi.parse('2019-01-01').d # => Tue | rday: 1 | rweek: 0
375
- puts EtOrbi.parse('2019-01-02').d # => Wed | rday: 2 | rweek: 0
376
- puts EtOrbi.parse('2019-01-31').d # => Thu | rday: 31 | rweek: 4
370
+ #### et-orbi >= 1.4.0 : reference set on Monday 2018-12-31
377
371
 
378
- puts EtOrbi.parse('2019-04-11').d # => Thu | rday: 101 | rweek: 14
379
- puts EtOrbi.parse('2025-09-30').d # => Tue | rday: 2465 | rweek: 352
372
+ Since 1.4.0, et-orbi starts by default on Monday (2018-12-31), as rday 0 with rweek 0.
380
373
 
381
- class EtOrbi::EoTime
382
- def d # debug
383
- "%14s | rday: %4d | rweek: %3d" % [ strftime('%F %a'), rday, rweek ]
384
- end
385
- end
374
+ Thus, the above code yields:
375
+ ```
376
+ * 2018-12-28 Fri / rday: -3 / rweek: -1
377
+ * 2018-12-29 Sat / rday: -2 / rweek: -1
378
+ * 2018-12-30 Sun / rday: -1 / rweek: -1
379
+
380
+ * 2018-12-31 Mon / rday: 0 / rweek: 0
381
+ * 2019-01-01 Tue / rday: 1 / rweek: 0
382
+ * 2019-01-02 Wed / rday: 2 / rweek: 0
383
+ * 2019-01-03 Thu / rday: 3 / rweek: 0
384
+ * 2019-01-04 Fri / rday: 4 / rweek: 0
385
+ * 2019-01-05 Sat / rday: 5 / rweek: 0
386
+
387
+ (...)
388
+
389
+ * 2025-10-04 Sat / rday: 2469 / rweek: 352
390
+ * 2025-10-05 Sun / rday: 2470 / rweek: 352
391
+
392
+ * 2025-10-06 Mon / rday: 2471 / rweek: 353
393
+ * 2025-10-07 Tue / rday: 2472 / rweek: 353
394
+ * 2025-10-08 Wed / rday: 2473 / rweek: 353
395
+ * 2025-10-09 Thu / rday: 2474 / rweek: 353
396
+ ```
386
397
 
387
- p EtOrbi.rweek_ref # => "2018-12-31"
388
398
 
389
- c = Fugit.parse_cron('20 0 * * mon%2,wed%3+1')
390
- puts c.next('2025-09-21').take(10).map(&:d)
391
- #
392
- # => 2025-09-29 Mon | rday: 2464 | rweek: 352
393
- # 2025-10-01 Wed | rday: 2466 | rweek: 352
394
- # 2025-10-13 Mon | rday: 2478 | rweek: 354
395
- # 2025-10-22 Wed | rday: 2487 | rweek: 355
396
- # 2025-10-27 Mon | rday: 2492 | rweek: 356
397
- # 2025-11-10 Mon | rday: 2506 | rweek: 358
398
- # 2025-11-12 Wed | rday: 2508 | rweek: 358
399
- # 2025-11-24 Mon | rday: 2520 | rweek: 360
400
- # 2025-12-03 Wed | rday: 2529 | rweek: 361
401
- # 2025-12-08 Mon | rday: 2534 | rweek: 362
402
- ```
403
-
404
- One can tell et-orbi >= 1.4.0 which day to take as reference:
399
+ #### modulo and et-orbi >= 1.4.0 sanity check
400
+
401
+ Given the cron `"0 12 * * mon%2,wed%3+1"`, here is a piece of code that considers a range of 44 days and tells in its last column if YES or no if each of the days matches the cron.
402
+
405
403
  ```ruby
406
- EtOrbi.rweek_ref = :us # or
407
- EtOrbi.rweek_ref = :sunday # to start on a Sunday (2018-12-30)
404
+ require 'fugit'
405
+
406
+ c = Fugit.parse_cron('0 12 * * mon%2,wed%3+1')
408
407
 
409
- EtOrbi.rweek_ref = :iso # or
410
- EtOrbi.rweek_ref = :monday # or
411
- EtOrbi.rweek_ref = :default # to start on a Monday (2019-12-31)
408
+ t = EtOrbi.parse('2025-09-20 12:00')
412
409
 
413
- EtOrbi.rweek_ref = :saturday # to start on, well, a Saturday (2019-01-05)
410
+ 44.times do
414
411
 
415
- EtOrbi.rweek_ref = '2025-09-30' # to start on this very Tuesday...
412
+ wd = t.strftime('%a')
413
+ wd = %w[ Mon Wed ].include?(wd) ? '*' + wd.upcase : ' ' + wd.downcase
416
414
 
417
- p EtOrbi.rweek_ref # to determine what the current setting is...
415
+ puts "%14s | rweek: %3d | %%2: %d == 0 | %%3: %d == 1 | ? %3s" % [
416
+ t.strftime('%F') + ' ' + wd,
417
+ t.rweek,
418
+ t.rweek % 2, t.rweek % 3,
419
+ c.match?(t)
420
+ ].map { |e| e == true ? 'YES' : e == false ? 'no' : e }
421
+
422
+ w = t.rweek
423
+ t = t.add(24 * 3600)
424
+ puts if t.rweek != w
425
+ end
426
+ ```
427
+
428
+ Here's the output:
429
+ ```
430
+ 2025-09-20 sat | rweek: 350 | %2: 0 == 0 | %3: 2 == 1 | ? no
431
+ 2025-09-21 sun | rweek: 350 | %2: 0 == 0 | %3: 2 == 1 | ? no
432
+
433
+ 2025-09-22 *MON | rweek: 351 | %2: 1 == 0 | %3: 0 == 1 | ? no
434
+ 2025-09-23 tue | rweek: 351 | %2: 1 == 0 | %3: 0 == 1 | ? no
435
+ 2025-09-24 *WED | rweek: 351 | %2: 1 == 0 | %3: 0 == 1 | ? no
436
+ 2025-09-25 thu | rweek: 351 | %2: 1 == 0 | %3: 0 == 1 | ? no
437
+ 2025-09-26 fri | rweek: 351 | %2: 1 == 0 | %3: 0 == 1 | ? no
438
+ 2025-09-27 sat | rweek: 351 | %2: 1 == 0 | %3: 0 == 1 | ? no
439
+ 2025-09-28 sun | rweek: 351 | %2: 1 == 0 | %3: 0 == 1 | ? no
440
+
441
+ 2025-09-29 *MON | rweek: 352 | %2: 0 == 0 | %3: 1 == 1 | ? YES
442
+ 2025-09-30 tue | rweek: 352 | %2: 0 == 0 | %3: 1 == 1 | ? no
443
+ 2025-10-01 *WED | rweek: 352 | %2: 0 == 0 | %3: 1 == 1 | ? YES
444
+ 2025-10-02 thu | rweek: 352 | %2: 0 == 0 | %3: 1 == 1 | ? no
445
+ 2025-10-03 fri | rweek: 352 | %2: 0 == 0 | %3: 1 == 1 | ? no
446
+ 2025-10-04 sat | rweek: 352 | %2: 0 == 0 | %3: 1 == 1 | ? no
447
+ 2025-10-05 sun | rweek: 352 | %2: 0 == 0 | %3: 1 == 1 | ? no
448
+
449
+ 2025-10-06 *MON | rweek: 353 | %2: 1 == 0 | %3: 2 == 1 | ? no
450
+ 2025-10-07 tue | rweek: 353 | %2: 1 == 0 | %3: 2 == 1 | ? no
451
+ 2025-10-08 *WED | rweek: 353 | %2: 1 == 0 | %3: 2 == 1 | ? no
452
+ 2025-10-09 thu | rweek: 353 | %2: 1 == 0 | %3: 2 == 1 | ? no
453
+ 2025-10-10 fri | rweek: 353 | %2: 1 == 0 | %3: 2 == 1 | ? no
454
+ 2025-10-11 sat | rweek: 353 | %2: 1 == 0 | %3: 2 == 1 | ? no
455
+ 2025-10-12 sun | rweek: 353 | %2: 1 == 0 | %3: 2 == 1 | ? no
456
+
457
+ 2025-10-13 *MON | rweek: 354 | %2: 0 == 0 | %3: 0 == 1 | ? YES
458
+ 2025-10-14 tue | rweek: 354 | %2: 0 == 0 | %3: 0 == 1 | ? no
459
+ 2025-10-15 *WED | rweek: 354 | %2: 0 == 0 | %3: 0 == 1 | ? no
460
+ 2025-10-16 thu | rweek: 354 | %2: 0 == 0 | %3: 0 == 1 | ? no
461
+ 2025-10-17 fri | rweek: 354 | %2: 0 == 0 | %3: 0 == 1 | ? no
462
+ 2025-10-18 sat | rweek: 354 | %2: 0 == 0 | %3: 0 == 1 | ? no
463
+ 2025-10-19 sun | rweek: 354 | %2: 0 == 0 | %3: 0 == 1 | ? no
464
+
465
+ 2025-10-20 *MON | rweek: 355 | %2: 1 == 0 | %3: 1 == 1 | ? no
466
+ 2025-10-21 tue | rweek: 355 | %2: 1 == 0 | %3: 1 == 1 | ? no
467
+ 2025-10-22 *WED | rweek: 355 | %2: 1 == 0 | %3: 1 == 1 | ? YES
468
+ 2025-10-23 thu | rweek: 355 | %2: 1 == 0 | %3: 1 == 1 | ? no
469
+ 2025-10-24 fri | rweek: 355 | %2: 1 == 0 | %3: 1 == 1 | ? no
470
+ 2025-10-25 sat | rweek: 355 | %2: 1 == 0 | %3: 1 == 1 | ? no
471
+ 2025-10-26 sun | rweek: 355 | %2: 1 == 0 | %3: 1 == 1 | ? no
472
+
473
+ 2025-10-27 *MON | rweek: 356 | %2: 0 == 0 | %3: 2 == 1 | ? YES
474
+ 2025-10-28 tue | rweek: 356 | %2: 0 == 0 | %3: 2 == 1 | ? no
475
+ 2025-10-29 *WED | rweek: 356 | %2: 0 == 0 | %3: 2 == 1 | ? no
476
+ 2025-10-30 thu | rweek: 356 | %2: 0 == 0 | %3: 2 == 1 | ? no
477
+ 2025-10-31 fri | rweek: 356 | %2: 0 == 0 | %3: 2 == 1 | ? no
478
+ 2025-11-01 sat | rweek: 356 | %2: 0 == 0 | %3: 2 == 1 | ? no
479
+ 2025-11-02 sun | rweek: 356 | %2: 0 == 0 | %3: 2 == 1 | ? no
418
480
  ```
419
481
 
420
482
 
data/lib/fugit/cron.rb CHANGED
@@ -731,7 +731,8 @@ module Fugit
731
731
  else
732
732
  a.collect(&:to_s).join('#')
733
733
  end }
734
- .join(',')
734
+ .join(',') +
735
+ (@day_and ? '&' : '')
735
736
  end
736
737
 
737
738
  module Parser include Raabro
data/lib/fugit/nat.rb CHANGED
@@ -719,6 +719,8 @@ module Fugit
719
719
  end
720
720
  end
721
721
 
722
+ SLASH_REGEX = /^(\d+|\*)\/(\d+)$/.freeze
723
+
722
724
  # Return nil if the cron is "not strict"
723
725
  #
724
726
  # For example, "0 0/17 * * *" (gh-86) is a perfectly valid
@@ -729,16 +731,18 @@ module Fugit
729
731
  #
730
732
  def restrict(a, cron)
731
733
 
732
- if m = ((a[1] && a[1][0]) || '').match(/^(\d+|\*)\/(\d+)$/)
733
- #p m
734
- sla = m[1].to_i
735
- return nil unless [ 1, 2, 3, 4, 5, 6, 8, 12 ].include?(sla)
734
+ if m = ((a[0] && a[0] != [ 0 ] && a[0][0]) || '').match(SLASH_REGEX)
735
+ return nil unless (1..60).include?(m[1].to_i)
736
+ end
737
+ if m = ((a[1] && a[1][0]) || '').match(SLASH_REGEX)
738
+ return nil unless [ 1, 2, 3, 4, 5, 6, 8, 12 ].include?(m[1].to_i)
736
739
  end
737
740
 
738
741
  cron
739
742
  end
740
743
 
741
744
  def slot(key, default)
745
+
742
746
  s = @slots[key]
743
747
  s ? s.data0 : [ default ]
744
748
  end
data/lib/fugit/parse.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Fugit
4
4
 
5
+ DO_PARSE_ORDER = %i[ cron duration nat at ].freeze
6
+
5
7
  class << self
6
8
 
7
9
  def parse_cron(s); ::Fugit::Cron.parse(s); end
@@ -34,7 +36,7 @@ module Fugit
34
36
  result = nil
35
37
  errors = []
36
38
 
37
- %i[ cron duration nat at ]
39
+ DO_PARSE_ORDER
38
40
  .each { |k|
39
41
  begin
40
42
  result ||= (opts[k] != false && self.send("do_parse_#{k}", s))
data/lib/fugit.rb CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Fugit
5
5
 
6
- VERSION = '1.12.0'
6
+ VERSION = '1.12.1'
7
7
  end
8
8
 
9
9
  require 'time'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fugit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.0
4
+ version: 1.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-09-30 00:00:00.000000000 Z
11
+ date: 2025-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: raabro