kronparser 0.0.3 → 0.0.4

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.
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
  - ''