cron_calc 0.1.0 → 0.2.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 +5 -2
- data/README.md +60 -10
- data/cron_calc.gemspec +3 -8
- data/lib/cron_calc/version.rb +1 -1
- data/lib/cron_calc.rb +53 -11
- metadata +8 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df5dd3a2f576d78996d783668af59a058a4fd9256072dfa25b84760d64e09797
|
4
|
+
data.tar.gz: 922e53ae27d369035d3b7fff81e1ba624756fa365c30694e6871abc54421473e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85a0d0ea11962ee78495e6c6c8ee40ea9695d20df2635efbb67cdc32502086032b3aa85aaa419b39cc1a736a31c6d1ecc577afd60b571d4e8d120c5adcd922fc
|
7
|
+
data.tar.gz: aab193b3c8afe9551dd46fe1b9e0061702cc69e3fa739c08c774d5f77ef40dabbd5c90c816b93a1e864d2e05c6c5278eda102c07649c83afd3a43553c5cc5ef8
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -4,25 +4,75 @@ CronCalc: A Ruby gem for calculating and analyzing scheduled CRON job occurrence
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
Install the gem by executing:
|
8
8
|
|
9
|
-
|
9
|
+
$ gem install cron_calc
|
10
10
|
|
11
|
-
|
11
|
+
## Usage
|
12
12
|
|
13
|
-
|
13
|
+
After installing `cron_calc` you can initialize `CronCalc` with the CRON string.
|
14
14
|
|
15
|
-
|
15
|
+
```ruby
|
16
|
+
require 'cron_calc'
|
17
|
+
cron_calc = CronCalc.new('5 5 * * *')
|
18
|
+
```
|
16
19
|
|
17
|
-
|
20
|
+
Now, you can use one of three methods `#in`, `#next`, `#last` to determine cron job occurrencies within specified period.
|
21
|
+
|
22
|
+
### Using `#in`
|
23
|
+
|
24
|
+
Calculates cron job occurrences within a given time period.
|
25
|
+
@param period [Range] The time period for which to calculate cron job occurrences.
|
26
|
+
@return [Array<Time>] An array of Time instances representing each occurrence.
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
period = Time.new(2024, 1, 1, 0, 0)..Time.new(2024, 1, 4, 0, 0)
|
30
|
+
cron_calc.in(period)
|
31
|
+
|
32
|
+
# => [2024-01-01 05:05:00 +0100, 2024-01-02 05:05:00 +0100, 2024-01-03 05:05:00 +0100]
|
33
|
+
```
|
34
|
+
|
35
|
+
### Using `#next`
|
36
|
+
|
37
|
+
Calculates the next 'n' occurrences of the cron job from a given start time.
|
38
|
+
@param count [Integer] The number of occurrences to calculate. Defaults to `1`.
|
39
|
+
@param period_start [Time] The start time from which to calculate occurrences. Defaults to `Time.now`.
|
40
|
+
@param max_years [Integer] The maximum number of years to consider for the period. Defaults to `5`.
|
41
|
+
@return [Array<Time>] An array of the next 'n' occurrences.
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
cron_calc.next
|
45
|
+
# => [2023-12-20 05:05:00 +0100]
|
46
|
+
|
47
|
+
cron_calc.next(3)
|
48
|
+
# => [2023-12-20 05:05:00 +0100, 2023-12-21 05:05:00 +0100, 2023-12-22 05:05:00 +0100]
|
49
|
+
|
50
|
+
cron_calc.next(2, Time.new(2024, 1, 1, 0, 0))
|
51
|
+
# => [2024-01-01 05:05:00 +0100, 2024-01-02 05:05:00 +0100]
|
52
|
+
```
|
53
|
+
|
54
|
+
### Using `#last`
|
55
|
+
|
56
|
+
Calculates the last 'n' occurrences of the cron job until a given end time.
|
57
|
+
@param count [Integer] The number of past occurrences to calculate.
|
58
|
+
@param period_end [Time] The end time until which to calculate occurrences.
|
59
|
+
@param max_years [Integer] The maximum number of years to consider for the period.
|
60
|
+
@return [Array<Time>] An array of the last 'n' occurrences.
|
18
61
|
|
19
|
-
|
62
|
+
```ruby
|
63
|
+
cron_calc.last
|
64
|
+
# => [2023-12-19 05:05:00 +0100]
|
20
65
|
|
21
|
-
|
66
|
+
cron_calc.last(4, Time.new(2024, 1, 1, 0, 0))
|
67
|
+
# => [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]
|
68
|
+
```
|
22
69
|
|
23
|
-
|
70
|
+
## Unsupported features
|
24
71
|
|
25
|
-
|
72
|
+
- DOW (Day of Week) - always require *
|
73
|
+
- Named DOW and months (SUN-SAT, JAN-DEC)
|
74
|
+
- Joining characters , - /
|
75
|
+
- Predefined definitions (@yearly, @monthly, @weekly, @daily, @midnight, @hourly)
|
26
76
|
|
27
77
|
## Contributing
|
28
78
|
|
data/cron_calc.gemspec
CHANGED
@@ -8,8 +8,9 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ['Jakub Miziński']
|
9
9
|
spec.email = ['jakubmizinski@gmail.com']
|
10
10
|
|
11
|
-
spec.summary = '
|
12
|
-
spec.description = '
|
11
|
+
spec.summary = 'Calculates cron job occurrences'
|
12
|
+
spec.description = 'Calculates cron job occurrences within a specified period \n
|
13
|
+
or determines next/last "n" occurrences based on a specified time.'
|
13
14
|
spec.homepage = 'https://github.com/mizinsky/cron_calc'
|
14
15
|
spec.license = 'MIT'
|
15
16
|
spec.required_ruby_version = '>= 2.6.0'
|
@@ -30,10 +31,4 @@ Gem::Specification.new do |spec|
|
|
30
31
|
spec.bindir = 'exe'
|
31
32
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
32
33
|
spec.require_paths = ['lib']
|
33
|
-
|
34
|
-
# Uncomment to register a new dependency of your gem
|
35
|
-
spec.add_dependency 'rspec', '~> 3.12'
|
36
|
-
|
37
|
-
# For more information and examples about making a new gem, check out our
|
38
|
-
# guide at: https://bundler.io/guides/creating_gem.html
|
39
34
|
end
|
data/lib/cron_calc/version.rb
CHANGED
data/lib/cron_calc.rb
CHANGED
@@ -7,15 +7,15 @@ require 'time'
|
|
7
7
|
module CronCalc
|
8
8
|
class Error < StandardError; end
|
9
9
|
|
10
|
-
def self.new(cron_string
|
11
|
-
Parser.new(cron_string
|
10
|
+
def self.new(cron_string)
|
11
|
+
Parser.new(cron_string)
|
12
12
|
end
|
13
13
|
|
14
14
|
# The Parser class provides functionality to parse and calculate occurrences
|
15
15
|
# of cron jobs within a given time period. It interprets cron strings and
|
16
16
|
# calculates when cron jobs will occur
|
17
17
|
class Parser
|
18
|
-
attr_reader :cron_string, :cron_parts
|
18
|
+
attr_reader :cron_string, :cron_parts
|
19
19
|
|
20
20
|
RANGE = {
|
21
21
|
minutes: 0..59,
|
@@ -24,24 +24,66 @@ module CronCalc
|
|
24
24
|
months: 1..12
|
25
25
|
}.freeze
|
26
26
|
|
27
|
-
def initialize(cron_string
|
27
|
+
def initialize(cron_string)
|
28
28
|
@cron_string = cron_string
|
29
|
-
|
29
|
+
|
30
|
+
raise 'Cron expression is not supported or invalid' unless cron_string_valid?
|
31
|
+
|
30
32
|
@cron_parts = split_cron_string
|
31
33
|
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
+
# Calculates cron job occurrences within a given time period.
|
36
|
+
# @param period [Range] The time period for which to calculate cron job occurrences.
|
37
|
+
# @return [Array<Time>] An array of Time instances representing each occurrence.
|
38
|
+
def in(period)
|
39
|
+
occurrences(period)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Calculates the next 'n' occurrences of the cron job from a given start time.
|
43
|
+
# @param count [Integer] The number of occurrences to calculate.
|
44
|
+
# @param period_start [Time] The start time from which to calculate occurrences.
|
45
|
+
# @param max_years [Integer] The maximum number of years to consider for the period.
|
46
|
+
# @return [Array<Time>] An array of the next 'n' occurrences.
|
47
|
+
def next(count = 1, period_start = Time.now, max_years = 5)
|
48
|
+
occurrences(
|
49
|
+
period_start..(period_start + (60 * 60 * 24 * 365 * max_years)),
|
50
|
+
count
|
51
|
+
)
|
52
|
+
end
|
35
53
|
|
36
|
-
|
54
|
+
# Calculates the last 'n' occurrences of the cron job until a given end time.
|
55
|
+
# @param count [Integer] The number of past occurrences to calculate.
|
56
|
+
# @param period_end [Time] The end time until which to calculate occurrences.
|
57
|
+
# @param max_years [Integer] The maximum number of years to consider for the period.
|
58
|
+
# @return [Array<Time>] An array of the last 'n' occurrences.
|
59
|
+
def last(count = 1, period_end = Time.now, max_years = 5)
|
60
|
+
occurrences(
|
61
|
+
(period_end - (60 * 60 * 24 * 365 * max_years))..period_end,
|
62
|
+
count,
|
63
|
+
reverse: true
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def occurrences(period, count = nil, reverse: false)
|
70
|
+
time_combinations = generate_time_combinations(period, reverse).lazy
|
71
|
+
|
72
|
+
time_combinations.each_with_object([]) do |(year, month, day, hour, minute), occ|
|
73
|
+
break occ if count && occ.length == count
|
37
74
|
|
38
|
-
years.product(months, days, hours, minutes).each_with_object([]) do |(year, month, day, hour, minute), occ|
|
39
75
|
time = Time.new(year, month, day, hour, minute)
|
40
76
|
occ << time if Date.valid_date?(year, month, day) && period.include?(time)
|
41
77
|
end
|
42
78
|
end
|
43
79
|
|
44
|
-
|
80
|
+
def generate_time_combinations(period, reverse)
|
81
|
+
minutes, hours, days, months = parse_cron_expression
|
82
|
+
years = (period.min.year..period.max.year).to_a
|
83
|
+
|
84
|
+
combinations = years.product(months, days, hours, minutes)
|
85
|
+
reverse ? combinations.reverse : combinations
|
86
|
+
end
|
45
87
|
|
46
88
|
def split_cron_string
|
47
89
|
splitted = cron_string.split
|
@@ -55,7 +97,7 @@ module CronCalc
|
|
55
97
|
end
|
56
98
|
|
57
99
|
def parse_cron_expression
|
58
|
-
%i[minutes hours days months].map { |unit| parse_cron_part(unit) }
|
100
|
+
%i[minutes hours days months].map { |unit| parse_cron_part(unit) }
|
59
101
|
end
|
60
102
|
|
61
103
|
# rubocop:disable Metrics
|
metadata
CHANGED
@@ -1,30 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cron_calc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.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-
|
12
|
-
dependencies:
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '3.12'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '3.12'
|
27
|
-
description: calculates cron job occurrences within a specified period
|
11
|
+
date: 2023-12-19 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |-
|
14
|
+
Calculates cron job occurrences within a specified period \n
|
15
|
+
or determines next/last "n" occurrences based on a specified time.
|
28
16
|
email:
|
29
17
|
- jakubmizinski@gmail.com
|
30
18
|
executables: []
|
@@ -64,8 +52,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
52
|
- !ruby/object:Gem::Version
|
65
53
|
version: '0'
|
66
54
|
requirements: []
|
67
|
-
rubygems_version: 3.
|
55
|
+
rubygems_version: 3.5.1
|
68
56
|
signing_key:
|
69
57
|
specification_version: 4
|
70
|
-
summary:
|
58
|
+
summary: Calculates cron job occurrences
|
71
59
|
test_files: []
|