cron_expression_generator 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4107dbe960196e694d0268b66f9074c81d292f2c28243540913d089e232906c4
4
+ data.tar.gz: d377c8047c9a4e3644e7cf3079f363a96f08d5ed65c0481d2be2937db2b91118
5
+ SHA512:
6
+ metadata.gz: 1e9213e9ed1f81ccec078f3495d4453d109d670ad41b453ac3d7e2c6caeb43056f1483b430d09fea28e019053768ed33161ff9df8dd733705f6a7c066eb2f0cc
7
+ data.tar.gz: 5925c84fd7199ea20500dcca73a0b20c10b909e4d6d9b99cd3a641cca46ec8e78d0869d5ff5340ee7c905d76dc73a98f7a37d765e825259cf9fa5e39fa09011f
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "cron_expression_generator"
4
+ puts CronExpressionGenerator.generate(start_time: ARGV[0], end_time: ARGV[1], interval_minutes: ARGV[2])
@@ -0,0 +1,191 @@
1
+ require 'date'
2
+ require 'active_support'
3
+ require 'active_support/core_ext'
4
+
5
+ class CronExpressionGenerator
6
+ def self.generate(start_time:, end_time:, interval_minutes:)
7
+ @start_time = start_time
8
+ @end_time = end_time
9
+ @interval_minutes = interval_minutes
10
+
11
+ self.validate_parameters
12
+ self.initialize
13
+
14
+ cron_expressions = []
15
+ if @count_up_time == @terminate_time
16
+ return cron_expressions # return empty if no time difference
17
+ end
18
+ @datetime_unit_to_match = self.get_largest_datetime_unit_diff
19
+ cron_expressions = self.match_largest_datetime_unit
20
+ cron_expressions += self.match_remaining_datetime
21
+ cron_expressions
22
+ end
23
+
24
+ private # --------------------------------------------------------
25
+
26
+ def self.initialize
27
+ if @start_time > @end_time
28
+ message = "start_time is larger than end_time.\n"
29
+ message += "given, start_time: #{@start_time}, end_time: #{@end_time}"
30
+ raise ArgumentError, message
31
+ end
32
+
33
+ @min = 'min'
34
+ @hour = 'hour'
35
+ @day = 'day'
36
+ @month = 'month'
37
+ @year = 'year'
38
+
39
+ @count_up_time = @start_time
40
+ @terminate_time = @end_time
41
+ @interval_minutes = @interval_minutes
42
+ end
43
+
44
+ def self.validate_parameters
45
+ begin
46
+ @start_time = DateTime.parse(@start_time) if @start_time.is_a?(String)
47
+ @end_time = DateTime.parse(@end_time) if @end_time.is_a?(String)
48
+ rescue
49
+ raise "Invalid given date format in String. Please pass the string in this format: YYYY-MM-DD HH:MM"
50
+ end
51
+ end
52
+
53
+ def self.carry_up_minutes_cron
54
+ "#{@count_up_time.min}-59/#{@interval_minutes} #{@count_up_time.hour} #{@count_up_time.day} #{@count_up_time.month} *"
55
+ end
56
+
57
+ def self.carry_up_hour_cron
58
+ "*/#{@interval_minutes} #{@count_up_time.hour}-23 #{@count_up_time.day} #{@count_up_time.month} *"
59
+ end
60
+
61
+ def self.carry_up_day_cron(last_day_of_month)
62
+ "*/#{@interval_minutes} * #{@count_up_time.day}-#{last_day_of_month} #{@count_up_time.month} *"
63
+ end
64
+
65
+ def self.carry_up_months_cron
66
+ "*/#{@interval_minutes} * * #{@count_up_time.month}-12 *"
67
+ end
68
+
69
+ def self.match_minutes_cron
70
+ "#{@count_up_time.min}-#{@terminate_time.min}/#{@interval_minutes} #{@terminate_time.hour} #{@terminate_time.day} #{@terminate_time.month} *"
71
+ end
72
+
73
+ def self.match_hour_cron
74
+ "*/#{@interval_minutes} #{@count_up_time.hour}-#{@terminate_time.hour.to_i - 1} #{@terminate_time.day} #{@terminate_time.month} *"
75
+ end
76
+
77
+ def self.match_day_cron
78
+ "*/#{@interval_minutes} * #{@count_up_time.day}-#{@terminate_time.day.to_i - 1} #{@terminate_time.month.to_i} *"
79
+ end
80
+
81
+ def self.match_months_cron
82
+ "*/#{@interval_minutes} * * #{@count_up_time.month}-#{@terminate_time.month.to_i - 1} *"
83
+ end
84
+
85
+ def self.get_largest_datetime_unit_diff
86
+ if @count_up_time.year != @terminate_time.year
87
+ @year
88
+ elsif @count_up_time.month != @terminate_time.month
89
+ @month
90
+ elsif @count_up_time.day != @terminate_time.day
91
+ @day
92
+ elsif @count_up_time.hour != @terminate_time.hour
93
+ @hour
94
+ elsif @count_up_time.min != @terminate_time.min
95
+ @min
96
+ else
97
+ message = "Unexpected value received to time_at & terminate_time_at.\n"
98
+ message += "given, count_up_time: #{@count_up_time}, terminate_time: #{@terminate_time}"
99
+ raise ArgumentError, message
100
+ end
101
+ end
102
+
103
+ def self.minutes_is_carried_up?
104
+ @datetime_unit_to_match != @min && @count_up_time.min != 0
105
+ end
106
+
107
+ def self.hour_is_carried_up?
108
+ @datetime_unit_to_match != @min && @datetime_unit_to_match != @hour && @count_up_time.hour != 0
109
+ end
110
+
111
+ def self.day_is_carried_up?
112
+ @datetime_unit_to_match != @min && @datetime_unit_to_match != @hour && @datetime_unit_to_match != @day && @count_up_time.day != 1
113
+ end
114
+
115
+ def self.months_is_carried_up?
116
+ @datetime_unit_to_match != @min && @datetime_unit_to_match != @hour && @datetime_unit_to_match != @day && @datetime_unit_to_match != @month && @count_up_time.month != 1
117
+ end
118
+
119
+ def self.minutes_is_matched?
120
+ @count_up_time.min == @terminate_time.min
121
+ end
122
+
123
+ def self.hour_is_matched?
124
+ @count_up_time.hour == @terminate_time.hour
125
+ end
126
+
127
+ def self.day_is_matched?
128
+ @count_up_time.day == @terminate_time.day
129
+ end
130
+
131
+ def self.months_is_matched?
132
+ @count_up_time.month == @terminate_time.month
133
+ end
134
+
135
+ def self.carry_up_time(time:, unit:)
136
+ if unit == @min
137
+ @count_up_time += time.minute
138
+ elsif unit == @hour
139
+ @count_up_time += time.hour
140
+ elsif unit == @day
141
+ @count_up_time += time.day
142
+ elsif unit == @month
143
+ @count_up_time += time.month
144
+ else
145
+ message = "Unexpected value passed to received to unit.\n"
146
+ message += "given, unit: #{unit}"
147
+ raise ArgumentError, message
148
+ end
149
+ end
150
+
151
+ def self.match_largest_datetime_unit
152
+ cron_expressions = []
153
+
154
+ # minutes
155
+ if self.minutes_is_carried_up?
156
+ cron_expressions.append(self.carry_up_minutes_cron)
157
+ remaining_minutes = 60 - @count_up_time.min.to_i
158
+ self.carry_up_time(time: remaining_minutes, unit: @min)
159
+ end
160
+ # hour
161
+ if self.hour_is_carried_up?
162
+ cron_expressions.append(self.carry_up_hour_cron)
163
+ remaining_hours = 24 - @count_up_time.hour.to_i
164
+ self.carry_up_time(time: remaining_hours, unit: @hour)
165
+ end
166
+ # day
167
+ if self.day_is_carried_up?
168
+ last_day_of_month = @count_up_time.end_of_month.strftime('%d').to_i
169
+ cron_expressions.append(self.carry_up_day_cron(last_day_of_month))
170
+ remaining_days = last_day_of_month - @count_up_time.day.to_i + 1
171
+ self.carry_up_time(time: remaining_days, unit: @day)
172
+ end
173
+ # months
174
+ if self.months_is_carried_up?
175
+ cron_expressions.append(self.carry_up_months_cron)
176
+ remaining_months = 12 - @count_up_time.month.to_i + 1
177
+ self.carry_up_time(time: remaining_months, unit: @month)
178
+ end
179
+
180
+ cron_expressions
181
+ end
182
+
183
+ def self.match_remaining_datetime
184
+ cron_expressions = []
185
+ cron_expressions.append(self.match_months_cron) unless self.months_is_matched?
186
+ cron_expressions.append(self.match_day_cron) unless self.day_is_matched?
187
+ cron_expressions.append(self.match_hour_cron) unless self.hour_is_matched?
188
+ cron_expressions.append(self.match_minutes_cron) unless self.minutes_is_matched?
189
+ cron_expressions
190
+ end
191
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cron_expression_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Itaru Kishikawa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-12-31 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This generates a set of cron expression(s) based on the given date and
14
+ interval minutes.
15
+ email: itaru.kishikawa@gmail.com
16
+ executables:
17
+ - cron_expression_generator
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/cron_expression_generator
22
+ - lib/cron_expression_generator.rb
23
+ homepage: https://rubygems.org/gems/cron_expression_generator
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubygems_version: 3.3.7
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Cron Expression Generator
46
+ test_files: []