cron_calc 0.4.0 → 1.0.0
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 +4 -4
- data/CHANGELOG.md +6 -1
- data/README.md +20 -4
- data/lib/cron_calc/version.rb +1 -1
- data/lib/cron_calc.rb +43 -29
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aebec718fd55bb74df49580abe4309a41ad0246b2c266a143f9dfac807cd436e
|
4
|
+
data.tar.gz: 1b47dea7541f369800f1f816fdf2160e0721de4a4f8bcdd9434c0b77fdf85876
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6f3349709b4a5babb3d2267f7e8cf1a7e2e51d9a118044e67743cc02b31d34bf5d637b068e825afe9f10c24e34c97a906730363a2c1c309eb003408b2c48586
|
7
|
+
data.tar.gz: fd80e141fd67e56adb122b6acf2dbbeff5572e69868212c749d1f6d67c422d70790a9910cec991a2ef328841f8fea17e2214c6276761124f5e4630f04c613557
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## [1.0.0] - 2023-12-28
|
2
|
+
|
3
|
+
- Add support for predefined definitions
|
4
|
+
- Add support for joining ,-
|
5
|
+
|
1
6
|
## [0.4.0] - 2023-12-22
|
2
7
|
|
3
8
|
- Added support for named months and wdays
|
@@ -5,7 +10,7 @@
|
|
5
10
|
|
6
11
|
## [0.3.0] - 2023-12-22
|
7
12
|
|
8
|
-
- Added support for DOWs
|
13
|
+
- Added support for DOWs (wdays)
|
9
14
|
|
10
15
|
## [0.2.0] - 2023-12-19
|
11
16
|
|
data/README.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# CronCalc
|
2
2
|
|
3
|
-
CronCalc
|
3
|
+
**CronCalc**: A Ruby gem for calculating CRON job occurrences. With this gem, you can easily determine when a cron job will occur by providing a cron expression. Key features include the ability to **calculate occurrences**:
|
4
|
+
- **Within a specified period**: Find out all the times your cron job will run during a particular timeframe.
|
5
|
+
- **After a given date**: Determine the next set of occurrences after a specific starting point.
|
6
|
+
- **Before a given date**: Discover when your cron job ran or would have run before a certain date.
|
7
|
+
|
8
|
+
This tool can be used for scheduling, forecasting, and analyzing tasks in systems that use cron for job scheduling.
|
4
9
|
|
5
10
|
## Installation
|
6
11
|
|
@@ -68,10 +73,21 @@ Calculates the last 'n' occurrences of the cron job until a given end time.\
|
|
68
73
|
# => [2023-12-31 05:05:00 +0100, 2023-12-30 05:05:00 +0100, 2023-12-29 05:05:00 +0100, 2023-12-28 05:05:00 +0100]
|
69
74
|
```
|
70
75
|
|
71
|
-
|
76
|
+
### Other examples
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
# You can omit the count parameter
|
80
|
+
CronCalc.new('5 5 */5 * SUN').last(before: Time.new(2020, 1, 1, 0, 0))
|
81
|
+
# => [2019-12-01 05:05:00 +0100]
|
72
82
|
|
73
|
-
|
74
|
-
|
83
|
+
# You can combine ',' and '-'
|
84
|
+
CronCalc.new('5 5 5-7,10 FEB *').next(5)
|
85
|
+
# => [2024-02-05 05:05:00 +0100, 2024-02-06 05:05:00 +0100, 2024-02-07 05:05:00 +0100, 2024-02-10 05:05:00 +0100, 2025-02-05 05:05:00 +0100]
|
86
|
+
|
87
|
+
# You can use predefined definitions like @daily, @monthly, etc.
|
88
|
+
CronCalc.new('@monthly').next(3, after: Time.new(2024, 1, 1, 0, 0))
|
89
|
+
# => [2024-01-01 00:00:00 +0100, 2024-02-01 00:00:00 +0100, 2024-03-01 00:00:00 +0100]
|
90
|
+
```
|
75
91
|
|
76
92
|
## Contributing
|
77
93
|
|
data/lib/cron_calc/version.rb
CHANGED
data/lib/cron_calc.rb
CHANGED
@@ -7,6 +7,33 @@ require 'time'
|
|
7
7
|
module CronCalc
|
8
8
|
class Error < StandardError; end
|
9
9
|
|
10
|
+
RANGE = {
|
11
|
+
minutes: 0..59,
|
12
|
+
hours: 0..23,
|
13
|
+
days: 1..31,
|
14
|
+
months: 1..12,
|
15
|
+
wdays: 0..6
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
WDAYS = {
|
19
|
+
'SUN' => '0', 'MON' => '1', 'TUE' => '2', 'WED' => '3',
|
20
|
+
'THU' => '4', 'FRI' => '5', 'SAT' => '6'
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
MONTHS = {
|
24
|
+
'JAN' => '1', 'FEB' => '2', 'MAR' => '3', 'APR' => '4',
|
25
|
+
'MAY' => '5', 'JUN' => '6', 'JUL' => '7', 'AUG' => '8',
|
26
|
+
'SEP' => '9', 'OCT' => '10', 'NOV' => '11', 'DEC' => '12'
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
PREDEFINED_DEFINITIONS = {
|
30
|
+
'@yearly' => '0 0 1 1 *', '@annually' => '0 0 1 1 *',
|
31
|
+
'@monthly' => '0 0 1 * *',
|
32
|
+
'@weekly' => '0 0 * * 0',
|
33
|
+
'@daily' => '0 0 * * *', '@midnight' => '0 0 * * *',
|
34
|
+
'@hourly' => '0 * * * *'
|
35
|
+
}.freeze
|
36
|
+
|
10
37
|
def self.new(cron_string)
|
11
38
|
Parser.new(cron_string)
|
12
39
|
end
|
@@ -17,30 +44,12 @@ module CronCalc
|
|
17
44
|
class Parser
|
18
45
|
attr_reader :cron_string, :cron_parts
|
19
46
|
|
20
|
-
RANGE = {
|
21
|
-
minutes: 0..59,
|
22
|
-
hours: 0..23,
|
23
|
-
days: 1..31,
|
24
|
-
months: 1..12,
|
25
|
-
wdays: 0..6
|
26
|
-
}.freeze
|
27
|
-
|
28
|
-
WDAYS = {
|
29
|
-
'SUN' => '0', 'MON' => '1', 'TUE' => '2', 'WED' => '3',
|
30
|
-
'THU' => '4', 'FRI' => '5', 'SAT' => '6'
|
31
|
-
}.freeze
|
32
|
-
|
33
|
-
MONTHS = {
|
34
|
-
'JAN' => '1', 'FEB' => '2', 'MAR' => '3', 'APR' => '4',
|
35
|
-
'MAY' => '5', 'JUN' => '6', 'JUL' => '7', 'AUG' => '8',
|
36
|
-
'SEP' => '9', 'OCT' => '10', 'NOV' => '11', 'DEC' => '12'
|
37
|
-
}.freeze
|
38
|
-
|
39
47
|
def initialize(cron_string)
|
40
48
|
@cron_string = cron_string
|
41
49
|
|
42
50
|
raise 'Cron expression is not supported or invalid' unless cron_string_valid?
|
43
51
|
|
52
|
+
@cron_string = normalize_with(cron_string, PREDEFINED_DEFINITIONS) if @cron_string.start_with? '@'
|
44
53
|
@cron_parts = split_cron_string
|
45
54
|
end
|
46
55
|
|
@@ -114,35 +123,40 @@ module CronCalc
|
|
114
123
|
%i[minutes hours days months].map { |unit| parse_cron_part(unit) }
|
115
124
|
end
|
116
125
|
|
117
|
-
# rubocop:disable Metrics
|
118
126
|
def parse_cron_part(time_unit)
|
119
127
|
range = RANGE[time_unit]
|
120
128
|
part = cron_parts[time_unit]
|
121
129
|
|
122
|
-
|
130
|
+
if part.include?(',')
|
131
|
+
part.split(',').flat_map { |e| parse_single_element(e, range) }.uniq.sort
|
132
|
+
else
|
133
|
+
parse_single_element(part, range)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def parse_single_element(element, range)
|
138
|
+
case element
|
123
139
|
when '*'
|
124
140
|
range.to_a
|
125
|
-
when /,/
|
126
|
-
part.split(',').map(&:to_i)
|
127
141
|
when /-/
|
128
|
-
(
|
142
|
+
(element.split('-').first.to_i..element.split('-').last.to_i).to_a
|
129
143
|
when %r{/}
|
130
|
-
range.step(
|
144
|
+
range.step(element.split('/').last.to_i).to_a
|
131
145
|
else
|
132
|
-
[
|
146
|
+
[element.to_i]
|
133
147
|
end
|
134
148
|
end
|
135
|
-
# rubocop:enable Metrics
|
136
149
|
|
137
150
|
def normalize_with(string, mapping)
|
138
151
|
mapping.inject(string) { |str, (k, v)| str.gsub(k, v) }
|
139
152
|
end
|
140
153
|
|
141
154
|
def cron_string_valid?
|
155
|
+
predefined = /\A@(yearly|annually|monthly|weekly|daily|midnight|hourly)\z/
|
142
156
|
# rubocop:disable Layout/LineLength
|
143
|
-
|
157
|
+
standard = %r{\A(\*|(\*/[0-5]?\d)|([0-5]?\d)(-(?:[0-5]?\d))?(,([0-5]?\d)(-(?:[0-5]?\d))?)*) (\*|(\*/[01]?\d|2[0-3])|([01]?\d|2[0-3])(-(?:[01]?\d|2[0-3]))?(,([01]?\d|2[0-3])(-(?:[01]?\d|2[0-3]))?)*|(\*/\d+)) (\*|(\*/[12]?\d|3[01])|([12]?\d|3[01])(-(?:[12]?\d|3[01]))?(,([12]?\d|3[01])(-(?:[12]?\d|3[01]))?)*|(\*/\d+)) (\*|(\*/[1-9]|1[0-2])|(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC|[1-9]|1[0-2])(-(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC|[1-9]|1[0-2]))?(,(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC|[1-9]|1[0-2])(-(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC|[1-9]|1[0-2]))?)*|(\*/\d+)) (\*|(\*/[0-6])|(SUN|MON|TUE|WED|THU|FRI|SAT|[0-6])(-(?:SUN|MON|TUE|WED|THU|FRI|SAT|[0-6]))?(,(SUN|MON|TUE|WED|THU|FRI|SAT|[0-6])(-(?:SUN|MON|TUE|WED|THU|FRI|SAT|[0-6]))?)*|(\*/[0-6]+))\z}
|
144
158
|
# rubocop:enable Layout/LineLength
|
145
|
-
cron_string.match?(
|
159
|
+
cron_string.match?(predefined) || cron_string.match?(standard)
|
146
160
|
end
|
147
161
|
end
|
148
162
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cron_calc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakub Miziński
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-12-
|
11
|
+
date: 2023-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |-
|
14
14
|
Calculates cron job occurrences within a specified period
|