fugit 1.3.4 → 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +83 -0
- data/CREDITS.md +16 -2
- data/LICENSE.txt +1 -1
- data/README.md +66 -6
- data/fugit.gemspec +3 -3
- data/lib/fugit/at.rb +1 -0
- data/lib/fugit/cron.rb +79 -28
- data/lib/fugit/duration.rb +7 -7
- data/lib/fugit/misc.rb +4 -0
- data/lib/fugit/nat.rb +590 -174
- data/lib/fugit/parse.rb +1 -0
- data/lib/fugit.rb +3 -1
- metadata +15 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd6f6af6264734f4eb10d5aa8e88cbcfbca029fb697f20b7a0ae37d220c55653
|
4
|
+
data.tar.gz: 25606c4f975d71350a360f4feb092a54f88bbb022fef31e4eb13c22d98b36b8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 253c2fc474a22ff93caa8b1f465af16565ab8b69037f7e83dc1e42719085d95342ee9d7a43200bdb05bcc9815dc29f590c5d86df51b7f526e25bb6d96dd4ef02
|
7
|
+
data.tar.gz: '0951e692d8026d3a66c374e99f872bd03270f77e93232bbbecefac44c8b9b17253b46218dbb36f9f009441bb6d602c04f40dad7782df31674e26244c1ce59055'
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,89 @@
|
|
2
2
|
# CHANGELOG.md
|
3
3
|
|
4
4
|
|
5
|
+
## fugit 1.5.3 released 2022-04-02
|
6
|
+
|
7
|
+
* Fix Fugit::Cron.to_s vs "0 13 * * wed%2", gh-68
|
8
|
+
|
9
|
+
|
10
|
+
## fugit 1.5.2 released 2021-09-18
|
11
|
+
|
12
|
+
* Simplify inc_day, gh-62
|
13
|
+
|
14
|
+
|
15
|
+
## fugit 1.5.1 released 2021-08-18
|
16
|
+
|
17
|
+
* Fix #next_time break issue for America/Santiago into DST, gh-60
|
18
|
+
|
19
|
+
|
20
|
+
## fugit 1.5.0 released 2021-06-08
|
21
|
+
|
22
|
+
* Accept "at 12 noon" and "at 12 midday" as "* 12 * * *", gh-57
|
23
|
+
* Accept "at 12pm" as "0 12 * * *", not "0 24 * * *", gh-57
|
24
|
+
* Accept "15/30 * * * *" as "15-59/30 * * * *", gh-56
|
25
|
+
|
26
|
+
|
27
|
+
## fugit 1.4.5 released 2021-04-22
|
28
|
+
|
29
|
+
* Accept "* * * Mon%2+2", gh-47
|
30
|
+
|
31
|
+
|
32
|
+
## fugit 1.4.4 released 2021-03-25
|
33
|
+
|
34
|
+
* Ensure leaving ZH DST is OK, gh-53
|
35
|
+
|
36
|
+
|
37
|
+
## fugit 1.4.3 released 2021-03-23
|
38
|
+
|
39
|
+
* Fix entering DST issue, gh-53
|
40
|
+
|
41
|
+
|
42
|
+
## fugit 1.4.2 released 2021-01-12
|
43
|
+
|
44
|
+
* Fix Fugit::Cron.previous_time vs last day of month, gh-51
|
45
|
+
* Let Fugit::Cron.parse('') return nil, gh-49
|
46
|
+
|
47
|
+
|
48
|
+
## fugit 1.4.1 released 2020-11-25
|
49
|
+
|
50
|
+
* Suppress warning, gh-46, thanks @amatsuda
|
51
|
+
|
52
|
+
|
53
|
+
## fugit 1.4.0 released 2020-10-27
|
54
|
+
|
55
|
+
* Ensure cron accepts "25-L" for monthday, gh-45
|
56
|
+
* Allow for "every weekday 8am to 5pm", gh-44
|
57
|
+
* Allow "every day from the 25th to the last", gh-45
|
58
|
+
* Rework nat parser
|
59
|
+
|
60
|
+
|
61
|
+
## fugit 1.3.9 released 2020-09-17
|
62
|
+
|
63
|
+
* Prevent "New York skip", gh-43, thanks @honglooker
|
64
|
+
|
65
|
+
|
66
|
+
## fugit 1.3.8 released 2020-08-06
|
67
|
+
|
68
|
+
* Parse 'every day at 8:30' and ' at 8:30 pm', gh-42
|
69
|
+
|
70
|
+
|
71
|
+
## fugit 1.3.7 released 2020-08-05
|
72
|
+
|
73
|
+
* Parse 'every 12 hours at minute 50', gh-41
|
74
|
+
|
75
|
+
|
76
|
+
## fugit 1.3.6 released 2020-06-01
|
77
|
+
|
78
|
+
* Introduce new nat syntaxed, gh-38
|
79
|
+
* Rework nat parser
|
80
|
+
|
81
|
+
|
82
|
+
## fugit 1.3.5 released 2020-05-07
|
83
|
+
|
84
|
+
* Implement cron @noon, gh-37
|
85
|
+
* Normalize "every x", gh-37
|
86
|
+
|
87
|
+
|
5
88
|
## fugit 1.3.4 released 2020-04-06
|
6
89
|
|
7
90
|
* Prevent #rough_frequency returning 0, gh-36
|
data/CREDITS.md
CHANGED
@@ -1,10 +1,24 @@
|
|
1
1
|
|
2
2
|
# fugit credits
|
3
3
|
|
4
|
+
* Peter Goldstein, https://github.com/petergoldstein GHA 3.3 j9.3, gh-65
|
5
|
+
* Pascal Zumkehr https://github.com/codez gh-62, Santiago into DST vs Time.zone
|
6
|
+
* Ggallardoh https://github.com/Ggallardoh gh-60, America/Santiago into DST
|
7
|
+
* Khaled AbuShqear https://github.com/shqear93 gh-57, "12pm"
|
8
|
+
* John W Higgins https://github.com/wishdev gh-56, 15/30 cron decision
|
9
|
+
* Karen Sawrey https://github.com/karensawrey gh-47, Mon%2+1 rework idea
|
10
|
+
* Olle Jonsson https://github.com/olleolleolle gha Ruby 3.0
|
11
|
+
* Andy Pfister https://github.com/andyundso gh-53, entering DST
|
12
|
+
* Solteszad https://github.com/solteszad gh-51, fix previous_time vs last day of month
|
13
|
+
* Niklas https://github.com/gr8bit gh-49, Fugit::Cron.parse('')
|
14
|
+
* Matsuda Akira https://github.com/amatsuda gh-46, warning suppression
|
15
|
+
* Honglooker https://github.com/honglooker gh-43, New York cron skip
|
16
|
+
* Jérôme Dalbert https://github.com/jeromedalbert gh-41, gh-42
|
17
|
+
* Danny Ben Shitrit https://github.com/DannyBen nat variants, gh-38
|
4
18
|
* Dominik Sander https://github.com/dsander #rough_frequency 0, gh-36
|
5
19
|
* Milovan Zogovic https://github.com/assembler Cron#match? vs TZ, gh-31
|
6
|
-
* Jessica Stokes https://github.com/ticky 0-24 issue with cron, gh-30
|
7
|
-
* Shai Coleman https://github.com/shaicoleman parse_nat enhancements, gh-24, gh-25, and gh-
|
20
|
+
* Jessica Stokes https://github.com/ticky 0-24 issue with cron, gh-30 and gh-47
|
21
|
+
* Shai Coleman https://github.com/shaicoleman parse_nat enhancements, gh-24, gh-25, gh-28, and gh-37
|
8
22
|
* Jan Stevens https://github.com/JanStevens Fugit.parse('every 15 minutes') gh-22
|
9
23
|
* Fabio Pitino https://github.com/hspazio nil on February 30 gh-21
|
10
24
|
* Cristian Oneț https://github.com/conet #previous_time vs 1/-1 endless loop gh-15
|
data/LICENSE.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
Copyright (c) 2017-
|
2
|
+
Copyright (c) 2017-2022, John Mettraux, jmettraux+flor@gmail.com
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
# fugit
|
3
3
|
|
4
|
-
[![
|
4
|
+
[![tests](https://github.com/floraison/fugit/workflows/test/badge.svg)](https://github.com/floraison/fugit/actions)
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/fugit.svg)](http://badge.fury.io/rb/fugit)
|
6
6
|
[![Join the chat at https://gitter.im/floraison/fugit](https://badges.gitter.im/floraison/fugit.svg)](https://gitter.im/floraison/fugit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
7
7
|
|
@@ -9,7 +9,7 @@ Time tools for [flor](https://github.com/floraison/flor) and the floraison group
|
|
9
9
|
|
10
10
|
It uses [et-orbi](https://github.com/floraison/et-orbi) to represent time instances and [raabro](https://github.com/floraison/raabro) as a basis for its parsers.
|
11
11
|
|
12
|
-
Fugit is a core dependency of [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler) 3.5.
|
12
|
+
Fugit is a core dependency of [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler) >= 3.5.
|
13
13
|
|
14
14
|
|
15
15
|
## Related projects
|
@@ -37,6 +37,7 @@ The intersection of those two projects is where fugit is born:
|
|
37
37
|
* [flor](https://github.com/floraison/flor) - used in the [cron](https://github.com/floraison/flor/blob/master/doc/procedures/cron.md) procedure
|
38
38
|
* [que-scheduler](https://github.com/hlascelles/que-scheduler) - a reliable job scheduler for [que](https://github.com/chanks/que)
|
39
39
|
* [serial_scheduler](https://github.com/grosser/serial_scheduler) - ruby task scheduler without threading
|
40
|
+
* [delayed_cron_job](https://github.com/codez/delayed_cron_job) - an extension to Delayed::Job that allows you to set cron expressions for your jobs
|
40
41
|
* ...
|
41
42
|
|
42
43
|
## `Fugit.parse(s)`
|
@@ -138,6 +139,8 @@ Example of cron strings understood by fugit:
|
|
138
139
|
# and more...
|
139
140
|
```
|
140
141
|
|
142
|
+
Please note that `'15/30 * * * *'` is interpreted as `'15-59/30 * * * *'` since fugit 1.4.6.
|
143
|
+
|
141
144
|
### the first Monday of the month
|
142
145
|
|
143
146
|
Fugit tries to follow the `man 5 crontab` documentation.
|
@@ -203,8 +206,22 @@ p EtOrbi.parse('2019-01-01').rweek % 2 # => 1
|
|
203
206
|
p EtOrbi.parse('2019-04-11').wday # => 4
|
204
207
|
p EtOrbi.parse('2019-04-11').rweek # => 15
|
205
208
|
p EtOrbi.parse('2019-04-11').rweek % 2 # => 1
|
209
|
+
|
210
|
+
c = Fugit.parse('* * * * tue%2')
|
211
|
+
c.match?('2019-01-01') # => false, since rweek % 2 == 1
|
212
|
+
c.match?('2019-01-08') # => true, since rweek % 2 == 0
|
213
|
+
|
214
|
+
c = Fugit.parse('* * * * tue%2+1')
|
215
|
+
c.match?('2019-01-01') # => true, since (rweek + 1) % 2 == 0
|
216
|
+
c.match?('2019-01-08') # => false, since (rweek + 1) % 2 == 1
|
217
|
+
|
218
|
+
# ...
|
206
219
|
```
|
207
220
|
|
221
|
+
`sun%2` matches if Sunday and `current_date.rweek % 2 == 0`
|
222
|
+
`tue%3+2` matches if Tuesday and `current_date.rweek + 2 % 3 == 0`
|
223
|
+
`tue%x+y` matches if Tuesday and `current_date.rweek + y % x == 0`
|
224
|
+
|
208
225
|
|
209
226
|
## `Fugit::Duration`
|
210
227
|
|
@@ -232,6 +249,29 @@ p d.to_plain_s # => "2Y2M1D5h3600s"
|
|
232
249
|
p Fugit::Duration.parse('1y2M1d4h').to_sec # => 36820800
|
233
250
|
```
|
234
251
|
|
252
|
+
There is a `#deflate` method
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
Fugit::Duration.parse(1000).to_plain_s # => "1000s"
|
256
|
+
Fugit::Duration.parse(3600).to_plain_s # => "3600s"
|
257
|
+
Fugit::Duration.parse(1000).deflate.to_plain_s # => "16m40s"
|
258
|
+
Fugit::Duration.parse(3600).deflate.to_plain_s # => "1h"
|
259
|
+
|
260
|
+
# or event shorter
|
261
|
+
Fugit.parse(1000).deflate.to_plain_s # => "16m40s"
|
262
|
+
Fugit.parse(3600).deflate.to_plain_s # => "1h"
|
263
|
+
```
|
264
|
+
|
265
|
+
There is also an `#inflate` method
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
Fugit::Duration.parse('1h30m12').inflate.to_plain_s # => "5412s"
|
269
|
+
Fugit.parse('1h30m12').inflate.to_plain_s # => "5412s"
|
270
|
+
|
271
|
+
Fugit.parse('1h30m12').to_sec # => 5412
|
272
|
+
Fugit.parse('1h30m12').to_sec.to_s + 's' # => "5412s"
|
273
|
+
```
|
274
|
+
|
235
275
|
The `to_*_s` methods are also available as class methods:
|
236
276
|
```ruby
|
237
277
|
p Fugit::Duration.to_plain_s('1y2M1d4h')
|
@@ -298,19 +338,39 @@ Fugit.parse('every day at five') # ==> Fugit::Cron instance '0 5 * * *'
|
|
298
338
|
|
299
339
|
### Ambiguous nats
|
300
340
|
|
301
|
-
Not all strings result in a clean, single, cron expression.
|
341
|
+
Not all strings result in a clean, single, cron expression. The `multi: false|true|:fail` argument to `Fugit::Nat.parse` could help.
|
302
342
|
|
303
343
|
```ruby
|
344
|
+
Fugit::Nat.parse('every day at 16:00 and 18:00')
|
345
|
+
.to_cron_s
|
346
|
+
# ==> '0 16,18 * * *' (a single Fugit::Cron instances)
|
304
347
|
Fugit::Nat.parse('every day at 16:00 and 18:00', multi: true)
|
305
|
-
|
348
|
+
.collect(&:to_cron_s)
|
349
|
+
# ==> [ '0 16,18 * * *' ] (array of Fugit::Cron instances, here only one)
|
350
|
+
|
306
351
|
Fugit::Nat.parse('every day at 16:15 and 18:30')
|
307
|
-
|
352
|
+
.to_cron_s
|
353
|
+
# ==> '15 16 * * *' (a single of Fugit::Cron instances)
|
308
354
|
Fugit::Nat.parse('every day at 16:15 and 18:30', multi: true)
|
309
|
-
|
355
|
+
.collect(&:to_cron_s)
|
356
|
+
# ==> [ '15 16 * * *', '30 18 * * *' ] (two Fugit::Cron instances)
|
357
|
+
|
310
358
|
Fugit::Nat.parse('every day at 16:15 and 18:30', multi: :fail)
|
311
359
|
# ==> ArgumentError: multiple crons in "every day at 16:15 and 18:30" (15 16 * * * | 30 18 * * *)
|
360
|
+
Fugit::Nat.parse('every day at 16:15 nada 18:30', multi: true)
|
361
|
+
# ==> nil
|
312
362
|
```
|
313
363
|
|
364
|
+
`multi: true` indicates to `Fugit::Nat` that an array of `Fugit::Cron` instances is expected as a result.
|
365
|
+
|
366
|
+
`multi: :fail` tells `Fugit::Nat.parse` to fail if the result is more than 1 `Fugit::Cron` instances.
|
367
|
+
|
368
|
+
`multi: false` is the default behaviour, return a single `Fugit::Cron` instance or nil when it cannot parse.
|
369
|
+
|
370
|
+
### Nat Midnight
|
371
|
+
|
372
|
+
`"Every day at midnight"` is supported, but `"Every monday at midnight"` will be interpreted (as of Fugit <= 1.4.x) as `"Every monday at 00:00"`. Sorry about that.
|
373
|
+
|
314
374
|
|
315
375
|
## LICENSE
|
316
376
|
|
data/fugit.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.platform = Gem::Platform::RUBY
|
11
11
|
s.authors = [ 'John Mettraux' ]
|
12
12
|
s.email = [ 'jmettraux+flor@gmail.com' ]
|
13
|
-
s.homepage = '
|
13
|
+
s.homepage = 'https://github.com/floraison/fugit'
|
14
14
|
s.license = 'MIT'
|
15
15
|
s.summary = 'time tools for flor'
|
16
16
|
|
@@ -40,8 +40,8 @@ Time tools for flor and the floraison project. Cron parsing and occurrence compu
|
|
40
40
|
#s.add_runtime_dependency 'tzinfo'
|
41
41
|
# this dependency appears in 'et-orbi'
|
42
42
|
|
43
|
-
s.add_runtime_dependency 'raabro', '~> 1.
|
44
|
-
s.add_runtime_dependency 'et-orbi', '~> 1
|
43
|
+
s.add_runtime_dependency 'raabro', '~> 1.4'
|
44
|
+
s.add_runtime_dependency 'et-orbi', '~> 1', '>= 1.2.7'
|
45
45
|
|
46
46
|
s.add_development_dependency 'rspec', '~> 3.8'
|
47
47
|
s.add_development_dependency 'chronic', '~> 0.10'
|
data/lib/fugit/at.rb
CHANGED
data/lib/fugit/cron.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module Fugit
|
3
4
|
|
@@ -11,9 +12,10 @@ module Fugit
|
|
11
12
|
'@weekly' => '0 0 * * 0',
|
12
13
|
'@daily' => '0 0 * * *',
|
13
14
|
'@midnight' => '0 0 * * *',
|
14
|
-
'@
|
15
|
+
'@noon' => '0 12 * * *',
|
16
|
+
'@hourly' => '0 * * * *' }.freeze
|
15
17
|
MAXDAYS = [
|
16
|
-
nil, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
|
18
|
+
nil, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ].freeze
|
17
19
|
|
18
20
|
attr_reader(
|
19
21
|
:original, :zone)
|
@@ -58,7 +60,7 @@ module Fugit
|
|
58
60
|
(@hours || [ '*' ]).join(','),
|
59
61
|
(@monthdays || [ '*' ]).join(','),
|
60
62
|
(@months || [ '*' ]).join(','),
|
61
|
-
|
63
|
+
weekdays_to_cron_s,
|
62
64
|
@timezone ? @timezone.name : nil
|
63
65
|
].compact.join(' ')
|
64
66
|
end
|
@@ -72,28 +74,44 @@ module Fugit
|
|
72
74
|
end
|
73
75
|
|
74
76
|
def time; @t; end
|
77
|
+
def to_t; @t; end
|
78
|
+
#
|
75
79
|
def to_i; @t.to_i; end
|
76
80
|
|
77
81
|
%w[ year month day wday hour min sec wday_in_month rweek rday ]
|
78
82
|
.collect(&:to_sym).each { |k| define_method(k) { @t.send(k) } }
|
79
83
|
|
80
|
-
def inc(i)
|
81
|
-
@t = @t + i
|
82
|
-
self
|
83
|
-
end
|
84
|
+
def inc(i); @t = @t + i; self; end
|
84
85
|
def dec(i); inc(-i); end
|
85
86
|
|
86
87
|
def inc_month
|
88
|
+
|
87
89
|
y = @t.year
|
88
90
|
m = @t.month + 1
|
89
91
|
if m == 13; m = 1; y += 1; end
|
92
|
+
|
90
93
|
@t = ::EtOrbi.make(y, m, @t.zone)
|
94
|
+
|
91
95
|
self
|
92
96
|
end
|
93
97
|
|
94
98
|
def inc_day
|
99
|
+
|
95
100
|
inc((24 - @t.hour) * 3600 - @t.min * 60 - @t.sec)
|
101
|
+
|
102
|
+
return if @t.hour == 0
|
103
|
+
|
104
|
+
if @t.hour < 12
|
105
|
+
begin
|
106
|
+
@t = ::EtOrbi.make(@t.year, @t.month, @t.day, @t.zone)
|
107
|
+
rescue ::TZInfo::PeriodNotFound
|
108
|
+
inc((24 - @t.hour) * 3600)
|
109
|
+
end
|
110
|
+
else
|
111
|
+
inc((24 - @t.hour) * 3600)
|
112
|
+
end
|
96
113
|
end
|
114
|
+
|
97
115
|
def inc_hour
|
98
116
|
inc((60 - @t.min) * 60 - @t.sec)
|
99
117
|
end
|
@@ -110,12 +128,7 @@ module Fugit
|
|
110
128
|
end
|
111
129
|
|
112
130
|
def dec_month
|
113
|
-
|
114
|
-
#dec(@t.day * 24 * 3600 + @t.hour * 3600 + @t.min * 60 + @t.sec + 1)
|
115
|
-
#
|
116
|
-
# gh-18, so that '0 9 29 feb *' doesn't get skipped (over and over)
|
117
|
-
#
|
118
|
-
dec(@t.day * 24 * 3600 + 1)
|
131
|
+
dec((@t.day - 1) * DAY_S + @t.hour * 3600 + @t.min * 60 + @t.sec + 1)
|
119
132
|
end
|
120
133
|
|
121
134
|
def dec_day
|
@@ -154,7 +167,7 @@ module Fugit
|
|
154
167
|
|
155
168
|
def weekday_modulo_match?(nt, mod)
|
156
169
|
|
157
|
-
nt.rweek % mod[0] ==
|
170
|
+
(nt.rweek + mod[1]) % mod[0] == 0
|
158
171
|
end
|
159
172
|
|
160
173
|
def weekday_match?(nt)
|
@@ -235,6 +248,8 @@ module Fugit
|
|
235
248
|
# the translation occurs in the timezone of
|
236
249
|
# this Fugit::Cron instance
|
237
250
|
|
251
|
+
zfrom = t.time.strftime('%z|%Z')
|
252
|
+
|
238
253
|
loop do
|
239
254
|
|
240
255
|
fail RuntimeError.new(
|
@@ -250,8 +265,14 @@ module Fugit
|
|
250
265
|
min_match?(t) || (t.inc_min; next)
|
251
266
|
sec_match?(t) || (t.inc_sec; next)
|
252
267
|
|
253
|
-
|
254
|
-
|
268
|
+
tt = t.time
|
269
|
+
st = tt.strftime('%F|%T')
|
270
|
+
zt = tt.strftime('%z|%Z')
|
271
|
+
#
|
272
|
+
if st == sfrom && zt != zfrom
|
273
|
+
from, sfrom, zfrom, ifrom = tt, st, zt, t.to_i
|
274
|
+
next
|
275
|
+
end
|
255
276
|
#
|
256
277
|
# when transitioning out of DST, this prevents #next_time from
|
257
278
|
# yielding the same literal time twice in a row, see gh-6
|
@@ -327,7 +348,7 @@ module Fugit
|
|
327
348
|
[ :seconds, 1, 60 ],
|
328
349
|
[ :minutes, 60, 60 ],
|
329
350
|
[ :hours, 3600, 24 ],
|
330
|
-
[ :days,
|
351
|
+
[ :days, DAY_S, 365 ] ].freeze
|
331
352
|
|
332
353
|
def rough_frequency
|
333
354
|
|
@@ -369,7 +390,7 @@ module Fugit
|
|
369
390
|
|
370
391
|
@delta_min = deltas.min; @delta_max = deltas.max
|
371
392
|
@occurrences = deltas.size
|
372
|
-
@span_years = span /
|
393
|
+
@span_years = span / YEAR_S
|
373
394
|
@yearly_occurrences = @occurrences.to_f / @span_years
|
374
395
|
end
|
375
396
|
|
@@ -481,12 +502,14 @@ module Fugit
|
|
481
502
|
|
482
503
|
sla = nil if sla == 1 # don't get fooled by /1
|
483
504
|
|
505
|
+
edn = max if sla && edn.nil?
|
506
|
+
|
484
507
|
return [ nil ] if sta.nil? && edn.nil? && sla.nil?
|
485
508
|
return [ sta ] if sta && edn.nil?
|
486
509
|
|
487
510
|
sla = 1 if sla == nil
|
488
511
|
sta = min if sta == nil
|
489
|
-
edn = max if edn == nil
|
512
|
+
edn = max if edn == nil || edn < 0 && sta > 0
|
490
513
|
|
491
514
|
range(min, max, sta, edn, sla)
|
492
515
|
end
|
@@ -498,12 +521,10 @@ module Fugit
|
|
498
521
|
{ min: min, max: max, sta: sta, edn: edn, sla: sla }.inspect
|
499
522
|
) if (sta < 0 && edn > 0) || (edn < 0 && sta > 0)
|
500
523
|
|
501
|
-
#p({ min: min, max: max, sta: sta, edn: edn, sla: sla })
|
502
524
|
a = []
|
503
525
|
|
504
526
|
omin, omax = min, max
|
505
527
|
min, max = -max, -1 if sta < 0
|
506
|
-
#p({ min: min, max: max })
|
507
528
|
|
508
529
|
cur = sta
|
509
530
|
|
@@ -601,12 +622,38 @@ module Fugit
|
|
601
622
|
@zone, @timezone = z
|
602
623
|
end
|
603
624
|
|
625
|
+
def weekdays_to_cron_s
|
626
|
+
|
627
|
+
return '*' unless @weekdays
|
628
|
+
|
629
|
+
@weekdays
|
630
|
+
.collect { |a|
|
631
|
+
if a.length == 1
|
632
|
+
a[0].to_s
|
633
|
+
elsif a[1].is_a?(Array)
|
634
|
+
a11 = a[1][1]
|
635
|
+
off = (a11 < 0) ? a11.to_s : (a11 > 0) ? "+#{a11}" : ''
|
636
|
+
"#{a[0]}%#{a[1][0]}" + off
|
637
|
+
else
|
638
|
+
a.collect(&:to_s).join('#')
|
639
|
+
end }
|
640
|
+
.join(',')
|
641
|
+
end
|
642
|
+
|
604
643
|
module Parser include Raabro
|
605
644
|
|
606
|
-
WEEKDAYS =
|
607
|
-
|
645
|
+
WEEKDAYS =
|
646
|
+
%w[ sunday monday tuesday wednesday thursday friday saturday ].freeze
|
608
647
|
|
609
|
-
|
648
|
+
WEEKDS =
|
649
|
+
WEEKDAYS.collect { |d| d[0, 3] }.freeze
|
650
|
+
DOW_REX =
|
651
|
+
/([0-7]|#{WEEKDS.join('|')})/i.freeze
|
652
|
+
|
653
|
+
MONTHS =
|
654
|
+
%w[ - jan feb mar apr may jun jul aug sep oct nov dec ].freeze
|
655
|
+
MONTH_REX =
|
656
|
+
/(1[0-2]|0?[1-9]|#{MONTHS[1..-1].join('|')})/i.freeze
|
610
657
|
|
611
658
|
# piece parsers bottom to top
|
612
659
|
|
@@ -620,8 +667,8 @@ module Fugit
|
|
620
667
|
def mos(i); rex(:mos, i, /[0-5]?\d/); end # min or sec
|
621
668
|
def hou(i); rex(:hou, i, /(2[0-4]|[01]?[0-9])/); end
|
622
669
|
def dom(i); rex(:dom, i, /(-?(3[01]|[12][0-9]|0?[1-9])|last|l)/i); end
|
623
|
-
def mon(i); rex(:mon, i,
|
624
|
-
def dow(i); rex(:dow, i,
|
670
|
+
def mon(i); rex(:mon, i, MONTH_REX); end
|
671
|
+
def dow(i); rex(:dow, i, DOW_REX); end
|
625
672
|
|
626
673
|
def dow_hash(i); rex(:hash, i, /#(-?[1-5]|last|l)/i); end
|
627
674
|
|
@@ -756,7 +803,7 @@ module Fugit
|
|
756
803
|
|
757
804
|
def rewrite_tz(t)
|
758
805
|
|
759
|
-
s = t.
|
806
|
+
s = t.strim
|
760
807
|
z = EtOrbi.get_tzone(s)
|
761
808
|
|
762
809
|
[ s, z ]
|
@@ -764,8 +811,12 @@ module Fugit
|
|
764
811
|
|
765
812
|
def rewrite_cron(t)
|
766
813
|
|
767
|
-
|
814
|
+
st = t
|
768
815
|
.sublookup(nil) # go to :ccron or :scron
|
816
|
+
|
817
|
+
return nil unless st
|
818
|
+
|
819
|
+
hcron = st
|
769
820
|
.subgather(nil) # list min, hou, mon, ...
|
770
821
|
.inject({}) { |h, tt|
|
771
822
|
h[tt.name] = tt.name == :tz ? rewrite_tz(tt) : rewrite_entry(tt)
|
data/lib/fugit/duration.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module Fugit
|
3
4
|
|
@@ -60,16 +61,15 @@ module Fugit
|
|
60
61
|
end
|
61
62
|
|
62
63
|
KEYS = {
|
63
|
-
yea: { a: 'Y', r: 'y', i: 'Y', s:
|
64
|
-
mon: { a: 'M', r: 'M', i: 'M', s: 30 *
|
65
|
-
wee: { a: 'W', r: 'w', i: 'W', s: 7 *
|
66
|
-
day: { a: 'D', r: 'd', i: 'D', s:
|
64
|
+
yea: { a: 'Y', r: 'y', i: 'Y', s: YEAR_S, x: 0, l: 'year' },
|
65
|
+
mon: { a: 'M', r: 'M', i: 'M', s: 30 * DAY_S, x: 1, l: 'month' },
|
66
|
+
wee: { a: 'W', r: 'w', i: 'W', s: 7 * DAY_S, I: true, l: 'week' },
|
67
|
+
day: { a: 'D', r: 'd', i: 'D', s: DAY_S, I: true, l: 'day' },
|
67
68
|
hou: { a: 'h', r: 'h', i: 'H', s: 3600, I: true, l: 'hour' },
|
68
69
|
min: { a: 'm', r: 'm', i: 'M', s: 60, I: true, l: 'minute' },
|
69
|
-
sec: { a: 's', r: 's', i: 'S', s: 1, I: true, l: 'second' }
|
70
|
-
}
|
70
|
+
sec: { a: 's', r: 's', i: 'S', s: 1, I: true, l: 'second' } }.freeze
|
71
71
|
INFLA_KEYS, NON_INFLA_KEYS =
|
72
|
-
KEYS.partition { |k, v| v[:I] }
|
72
|
+
KEYS.partition { |k, v| v[:I] }.freeze
|
73
73
|
|
74
74
|
def _to_s(key)
|
75
75
|
|