cron_calc 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29ac47b06a1dc188f3fb9ed5c10f9fa1a6ef748e8d15a6783eb7b8f99de85b38
4
- data.tar.gz: 8f136ff6c1010357acd75942e80bc7d4a2f4b0d1b8555041486f1cc9bdd97f00
3
+ metadata.gz: aebec718fd55bb74df49580abe4309a41ad0246b2c266a143f9dfac807cd436e
4
+ data.tar.gz: 1b47dea7541f369800f1f816fdf2160e0721de4a4f8bcdd9434c0b77fdf85876
5
5
  SHA512:
6
- metadata.gz: 38f8b7a5a0f80d10f6c4867a8a2e687b9ebb508c5e79031856cbb9bc81a9a97b6f399e0b37f332f5ec5aeb7d2839e29d11b6e76b0fdc5601b675a6a5ed82e806
7
- data.tar.gz: d1545c32cd0559370fc1778c3517567ee0be5f4fecf41ad32af0a2a3fd3202d52f0b9d5014f202ab736c8174675d2c7692610fa72968f247022082aa7a2b5567
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: A Ruby gem for calculating and analyzing scheduled CRON job occurrences and timings within specified intervals.
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
- ## Unsupported features
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
- - Joining characters , - /
74
- - Predefined definitions (@yearly, @monthly, @weekly, @daily, @midnight, @hourly)
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CronCalc
4
- VERSION = '0.4.0'
4
+ VERSION = '1.0.0'
5
5
  end
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
- case part
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
- (part.split('-').first.to_i..part.split('-').last.to_i).to_a
142
+ (element.split('-').first.to_i..element.split('-').last.to_i).to_a
129
143
  when %r{/}
130
- range.step(part.split('/').last.to_i).to_a
144
+ range.step(element.split('/').last.to_i).to_a
131
145
  else
132
- [part.to_i]
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
- regex = %r{\A(\*|([0-5]?\d)(,([0-5]?\d))*|(\*/\d+)|(\d+-\d+)) (\*|([01]?\d|2[0-3])(,([01]?\d|2[0-3]))*|(\*/\d+)|(\d+-\d+)) (\*|([12]?\d|3[01])(,([12]?\d|3[01]))*|(\*/\d+)|(\d+-\d+)) (\*|(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))*|(\*/\d+)|(\d+-\d+)) (\*|(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]-[0-6]))\z}
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?(regex)
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.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-22 00:00:00.000000000 Z
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