kronparser 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -26,8 +26,10 @@ Usage
26
26
  require 'kronparser'
27
27
  require 'time'
28
28
 
29
- KronParser.parser("* * * * *").next(Time.parse("Fri Oct 26 11:27:44 +0900 2012"))
29
+ KronParser.parse("* * * * *").next(Time.parse("Fri Oct 26 11:27:44 +0900 2012"))
30
30
  # => Fri Oct 26 11:28:00 +0900 2012
31
+ KronParser.parse("40 * * * *").next(Time.parse("Fri Oct 26 11:27:44 +0900 2012"))
32
+ # => Fri Oct 26 10:40:00 +0900 2012
31
33
  ```
32
34
 
33
35
  * Example2
@@ -35,7 +37,7 @@ KronParser.parser("* * * * *").next(Time.parse("Fri Oct 26 11:27:44 +0900 2012")
35
37
  ```
36
38
  require 'kronparser'
37
39
 
38
- KronParser.parser("* * * * *").next
40
+ KronParser.parse("* * * * *").next
39
41
  # => Fri Oct 26 11:28:00 +0900 2012
40
42
  # Default value is Time.now
41
43
  ```
@@ -13,7 +13,7 @@ class KronParser
13
13
 
14
14
  MONTH_LAST_DATE = {
15
15
  1 => 31,
16
- 2 => 29,
16
+ 2 => 28,
17
17
  3 => 31,
18
18
  4 => 30,
19
19
  5 => 31,
@@ -61,7 +61,7 @@ class KronParser
61
61
  time.send(time_item) + forward,
62
62
  :mon => time.mon,
63
63
  :year => time.year)
64
- if (forward == 1) || (time_data[time_item] != time.send(time_item))
64
+ if (forward != 0) || (time_data[time_item] != time.send(time_item))
65
65
  idx.times do |i|
66
66
  time_data[time_items[i]] = first_elem(time_items[i], :mon => time.mon, :year => time.year)
67
67
  end
@@ -86,8 +86,39 @@ class KronParser
86
86
  return Time.local(time_data[:year], time_data[:mon], time_data[:day], time_data[:hour], time_data[:min])
87
87
  end
88
88
 
89
- def last(time = TIme.now)
90
- Time.now
89
+ def prev(time = TIme.now)
90
+ return nil unless @is_time_exist
91
+
92
+ back = 0
93
+ time_items = [:min, :hour, :day, :mon]
94
+ time_data = {}
95
+ time_items.each_with_index do |time_item, idx|
96
+ time_data[time_item], back = prev_elem(time_item,
97
+ time.send(time_item) - back,
98
+ :mon => time.mon,
99
+ :year => time.year)
100
+ if (back != 0) || (time_data[time_item] != time.send(time_item))
101
+ idx.times do |i|
102
+ time_data[time_items[i]] = last_elem(time_items[i], :mon => time.mon, :year => time.year)
103
+ end
104
+ end
105
+ end
106
+ time_data[:year] = time.year - back
107
+
108
+ date = nil
109
+ while date.nil?
110
+ date = Date.new(time_data[:year], time_data[:mon], time_data[:day]) rescue nil
111
+ next if date
112
+
113
+ time_data[:min] = last_elem(:min)
114
+ time_data[:hour] = last_elem(:hour)
115
+
116
+ time_data[:day], back = prev_elem(:day, time_data[:day] - 1, time_data)
117
+ time_data[:mon], back = prev_elem(:mon, time_data[:mon] - back)
118
+ time_data[:year] -= back
119
+ end
120
+
121
+ return Time.local(time_data[:year], time_data[:mon], time_data[:day], time_data[:hour], time_data[:min])
91
122
  end
92
123
 
93
124
  private
@@ -95,7 +126,7 @@ class KronParser
95
126
  def time_exist?
96
127
  return true if @day_type != :day
97
128
  @data[:mon].each do |mon|
98
- last_date = MONTH_LAST_DATE[mon]
129
+ last_date = MONTH_LAST_DATE[mon] + (mon == 2 ? 1 : 0)
99
130
  return true if last_date == 31
100
131
  return true if @data[:day].find { |x| x <= last_date }
101
132
  end
@@ -122,6 +153,26 @@ class KronParser
122
153
  end
123
154
  end
124
155
 
156
+ def last_elem(type, options = {})
157
+ if (type != :day) || (@day_type == :day)
158
+ return @data[type].last
159
+ end
160
+
161
+ value = nil
162
+ last_mon, back = prev_elem(:mon, options[:mon] - 1)
163
+ date = Date.new(options[:year] - back, last_mon, MONTH_LAST_DATE[last_mon])
164
+ date = date.next if date.leap?
165
+ last_wday = @data[:wday].reverse.find { |x| x <= date.wday }
166
+ value = date.day + (last_wday ? (last_wday - date.wday) : (-7 - date.wday + @data[:wday].last))
167
+
168
+ case @day_type
169
+ when :wday
170
+ return value
171
+ when :each
172
+ return [value, @data[type].last].max
173
+ end
174
+ end
175
+
125
176
  def next_elem(type, value, options = {})
126
177
  next_value = forward = nil
127
178
 
@@ -150,7 +201,36 @@ class KronParser
150
201
  return *(((forward > wday_forward) || ((forward == wday_forward) && (next_value > next_wday_value))) ? [next_wday_value, wday_forward] : [next_value, forward])
151
202
  end
152
203
  end
153
-
204
+
205
+ def prev_elem(type, value, options = {})
206
+ last_value = back = nil
207
+
208
+ if (type != :day) || (@day_type != :wday)
209
+ last_value = @data[type].reverse.find { |x| x <= value }
210
+ back = last_value.nil? ? 1 : 0
211
+ last_value = last_elem(type, options) unless last_value
212
+
213
+ return last_value, back if (type != :day) || (@day_type == :day)
214
+ end
215
+
216
+ wday_back = 1
217
+ last_wday_value = nil
218
+ date = Date.new(options[:year], options[:mon], value) rescue nil
219
+ if date
220
+ last_wday = @data[:wday].reverse.find { |x| x <= date.wday }
221
+ last_wday_value = value + (last_wday ? (last_wday - date.wday) : (-7 - date.wday + @data[:wday].last))
222
+ wday_back = 0 if last_wday_value > 0
223
+ end
224
+ last_wday_value = last_elem(type, options) if wday_back == 1
225
+
226
+ case @day_type
227
+ when :wday
228
+ return last_wday_value, wday_back
229
+ when :each
230
+ return *(((back > wday_back) || ((back == wday_back) && (last_value < last_wday_value))) ? [last_wday_value, wday_back] : [last_value, back])
231
+ end
232
+ end
233
+
154
234
  def parse_elem(format, range)
155
235
  case format
156
236
  when /,/
@@ -1,3 +1,3 @@
1
1
  class KronParser
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -136,6 +136,93 @@ describe KronParser do
136
136
  end
137
137
  end
138
138
 
139
+ it "could get prev time" do
140
+ test_data = [
141
+ ["1 * * * *", :prev, "2011/12/21 12:31:52", "2011/12/21 12:01:00"],
142
+ ["* 1 * * *", :prev, "2011/12/21 12:31:52", "2011/12/21 01:59:00"],
143
+ ["* * 1 * *", :prev, "2011/12/21 12:31:52", "2011/12/01 23:59:00"],
144
+ ["* * * 1 *", :prev, "2011/12/21 12:31:52", "2011/01/31 23:59:00"],
145
+ ["* * * * 1", :prev, "2011/12/21 12:31:52", "2011/12/19 23:59:00"],
146
+ ["* * * * *", :prev, "2011/12/21 12:31:52", "2011/12/21 12:31:00"],
147
+
148
+ ["5,30 * * * *", :prev, "2011/12/21 12:01:52", "2011/12/21 11:30:00"],
149
+ ["5,30 * * * *", :prev, "2011/12/21 12:04:52", "2011/12/21 11:30:00"],
150
+ ["5,30 * * * *", :prev, "2011/12/21 12:05:52", "2011/12/21 12:05:00"],
151
+ ["5,30 * * * *", :prev, "2011/12/21 12:06:52", "2011/12/21 12:05:00"],
152
+ ["5,30 * * * *", :prev, "2011/12/21 12:29:52", "2011/12/21 12:05:00"],
153
+ ["5,30 * * * *", :prev, "2011/12/21 12:30:52", "2011/12/21 12:30:00"],
154
+ ["5,30 * * * *", :prev, "2011/12/21 12:31:52", "2011/12/21 12:30:00"],
155
+ ["5,30 * * * *", :prev, "2011/12/21 12:40:52", "2011/12/21 12:30:00"],
156
+
157
+ ["5,30 * * * *", :prev, "2011/12/21 12:50:52", "2011/12/21 12:30:00"],
158
+ ["5,30 * * * *", :prev, "2011/12/21 12:01:52", "2011/12/21 11:30:00"],
159
+ ["5,30 * * * *", :prev, "2011/12/21 00:01:52", "2011/12/20 23:30:00"],
160
+ ["5,30 * * * *", :prev, "2011/12/01 00:01:52", "2011/11/30 23:30:00"],
161
+ ["5,30 * * * *", :prev, "2011/01/01 00:01:52", "2010/12/31 23:30:00"],
162
+
163
+ ["5,30 * * * *", :prev, "2012/01/01 00:01:52", "2011/12/31 23:30:00"],
164
+ ["5,30 * * * *", :prev, "2012/02/01 00:01:52", "2012/01/31 23:30:00"],
165
+ ["5,30 * * * *", :prev, "2012/03/01 00:01:52", "2012/02/29 23:30:00"],
166
+ ["5,30 * * * *", :prev, "2012/04/01 00:01:52", "2012/03/31 23:30:00"],
167
+ ["5,30 * * * *", :prev, "2012/05/01 00:01:52", "2012/04/30 23:30:00"],
168
+ ["5,30 * * * *", :prev, "2012/06/01 00:01:52", "2012/05/31 23:30:00"],
169
+ ["5,30 * * * *", :prev, "2012/07/01 00:01:52", "2012/06/30 23:30:00"],
170
+ ["5,30 * * * *", :prev, "2012/08/01 00:01:52", "2012/07/31 23:30:00"],
171
+ ["5,30 * * * *", :prev, "2012/09/01 00:01:52", "2012/08/31 23:30:00"],
172
+ ["5,30 * * * *", :prev, "2012/10/01 00:01:52", "2012/09/30 23:30:00"],
173
+ ["5,30 * * * *", :prev, "2012/11/01 00:01:52", "2012/10/31 23:30:00"],
174
+ ["5,30 * * * *", :prev, "2012/12/01 00:01:52", "2012/11/30 23:30:00"],
175
+ ["5,30 * * * *", :prev, "2013/01/01 00:01:52", "2012/12/31 23:30:00"],
176
+ ["5,30 * * * *", :prev, "2011/03/01 00:01:52", "2011/02/28 23:30:00"],
177
+
178
+ ["* 5 * * *", :prev, "2011/03/02 10:10:52", "2011/03/02 05:59:00"],
179
+ ["* 5 * * *", :prev, "2011/03/02 05:59:00", "2011/03/02 05:59:00"],
180
+ ["* 5 * * *", :prev, "2011/03/02 05:00:00", "2011/03/02 05:00:00"],
181
+ ["* 5 * * *", :prev, "2011/03/02 04:59:00", "2011/03/01 05:59:00"],
182
+ ["* 5 * * *", :prev, "2011/03/01 04:59:00", "2011/02/28 05:59:00"],
183
+ ["* 5 * * *", :prev, "2011/01/01 04:59:00", "2010/12/31 05:59:00"],
184
+
185
+ ["* * 5 * *", :prev, "2011/01/31 04:59:00", "2011/01/05 23:59:00"],
186
+ ["* * 5 * *", :prev, "2011/02/04 23:59:00", "2011/01/05 23:59:00"],
187
+ ["* * 5 * *", :prev, "2011/01/04 23:59:00", "2010/12/05 23:59:00"],
188
+
189
+ ["* * * 5 *", :prev, "2011/05/23 04:59:34", "2011/05/23 04:59:00"],
190
+ ["* * * 5 *", :prev, "2011/10/01 04:59:00", "2011/05/31 23:59:00"],
191
+ ["* * * 5 *", :prev, "2011/04/30 23:59:59", "2010/05/31 23:59:00"],
192
+
193
+ ["* * * * 5", :prev, "2011/04/30 23:59:59", "2011/04/29 23:59:00"],
194
+ ["* * * * 5", :prev, "2011/04/28 23:59:59", "2011/04/22 23:59:00"],
195
+ ["* * * * 5", :prev, "2011/03/03 23:59:59", "2011/02/25 23:59:00"],
196
+ ["* * * * 5", :prev, "2011/01/06 23:59:59", "2010/12/31 23:59:00"],
197
+ ["* * * * 3,5", :prev, "2011/04/30 23:59:59", "2011/04/29 23:59:00"],
198
+ ["* * * * 3,5", :prev, "2011/04/29 12:12:59", "2011/04/29 12:12:00"],
199
+ ["* * * * 3,5", :prev, "2011/04/28 23:59:59", "2011/04/27 23:59:00"],
200
+ ["* * * * 3,5", :prev, "2011/04/27 12:12:59", "2011/04/27 12:12:00"],
201
+ ["* * * * 3,5", :prev, "2011/04/26 23:59:59", "2011/04/22 23:59:00"],
202
+
203
+ ["* * 2 * 5", :prev, "2011/02/05 23:59:59", "2011/02/04 23:59:00"],
204
+ ["* * 2 * 5", :prev, "2011/02/04 23:59:59", "2011/02/04 23:59:00"],
205
+ ["* * 2 * 5", :prev, "2011/02/03 23:59:59", "2011/02/02 23:59:00"],
206
+ ["* * 2 * 5", :prev, "2011/02/02 23:59:59", "2011/02/02 23:59:00"],
207
+ ["* * 2 * 5", :prev, "2011/02/01 23:59:59", "2011/01/28 23:59:00"],
208
+ ["* * 2 * 5", :prev, "2011/01/01 23:59:59", "2010/12/31 23:59:00"],
209
+
210
+ ["* * 27 * 5", :prev, "2011/02/28 23:59:59", "2011/02/27 23:59:00"],
211
+ ["* * 27 * 5", :prev, "2011/02/27 23:59:59", "2011/02/27 23:59:00"],
212
+ ["* * 27 * 5", :prev, "2011/02/26 23:59:59", "2011/02/25 23:59:00"],
213
+ ["* * 27 * 5", :prev, "2011/02/25 23:59:59", "2011/02/25 23:59:00"],
214
+ ["* * 27 * 5", :prev, "2011/03/02 23:59:59", "2011/02/27 23:59:00"],
215
+ ["* * 30 * 1", :prev, "2011/01/01 23:59:59", "2010/12/30 23:59:00"],
216
+
217
+ ["* * 29 2 *", :prev, "2011/05/01 23:59:59", "2008/02/29 23:59:00"],
218
+ ]
219
+
220
+ test_data.each do |cron_time_format, target_method, now_date, get_date|
221
+ result_date = KronParser.parse(cron_time_format).send(target_method, Time.parse(now_date))
222
+ result_date.should == Time.parse(get_date)
223
+ end
224
+ end
225
+
139
226
  it "could get nil if next time is not exist" do
140
227
  data = [
141
228
  ["* * 31 1 *", :next, "2012/01/31 23:59:59", "2013/01/31 00:00:00"],
@@ -168,6 +255,17 @@ describe KronParser do
168
255
  end
169
256
  end
170
257
 
258
+ it "could get nil if prev time is not exist" do
259
+ data = [
260
+ ["* * 31 2 *", :prev, "2012/01/31 23:59:59", nil],
261
+ ]
262
+
263
+ data.each do |cron_time_format, target_method, now_date, get_date|
264
+ result_date = KronParser.parse(cron_time_format).send(target_method, Time.parse(now_date))
265
+ result_date.should == (get_date ? Time.parse(get_date) : nil)
266
+ end
267
+ end
268
+
171
269
  it "should raise ArgmentError when value is out of range" do
172
270
  data = [
173
271
  ["-1 * * * *", false],
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kronparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-27 00:00:00.000000000 Z
12
+ date: 2012-10-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70325128253200 !ruby/object:Gem::Requirement
16
+ requirement: &70314147481600 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70325128253200
24
+ version_requirements: *70314147481600
25
25
  description: datermine next scheduled crontab run
26
26
  email:
27
27
  - ''