ice_cube 0.11.1 → 0.11.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ice_cube/rule.rb +1 -1
- data/lib/ice_cube/schedule.rb +41 -25
- data/lib/ice_cube/version.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- metadata +14 -19
- data/lib/ice_cube/enumerator.rb +0 -63
- data/lib/ice_cube/hash_input.rb +0 -71
- data/lib/ice_cube/string_helpers.rb +0 -10
- data/lib/ice_cube/time_step.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad4d50b4bb41ce4aa716c1e8a21881ef46c5d392
|
4
|
+
data.tar.gz: 8b056f0639eedf325853e14a7218bb413f73b534
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fbb5f63f50525151a1a4e5e8725b32d84fcf32ce766800f3e297be2662786bfda057ce59cd968ebd89aae321ed6943ef9d4a9bb3a9c539850f2d913689f2224
|
7
|
+
data.tar.gz: 261ff22883b072727b92e966610742a08908f91808341b180c02a55160ab6be12748545ee90a5d4c6c9c04ce2cd918a567f4b46e887ad50078f0e5495f2061ec
|
data/lib/ice_cube/rule.rb
CHANGED
data/lib/ice_cube/schedule.rb
CHANGED
@@ -145,60 +145,78 @@ module IceCube
|
|
145
145
|
# Get all of the occurrences from the start_time up until a
|
146
146
|
# given Time
|
147
147
|
def occurrences(closing_time)
|
148
|
-
|
148
|
+
enumerate_occurrences(start_time, closing_time).to_a
|
149
149
|
end
|
150
150
|
|
151
151
|
# All of the occurrences
|
152
152
|
def all_occurrences
|
153
153
|
require_terminating_rules
|
154
|
-
|
154
|
+
enumerate_occurrences(start_time).to_a
|
155
|
+
end
|
156
|
+
|
157
|
+
# Emit an enumerator based on the start time
|
158
|
+
def all_occurrences_enumerator
|
159
|
+
enumerate_occurrences(start_time)
|
155
160
|
end
|
156
161
|
|
157
162
|
# Iterate forever
|
158
163
|
def each_occurrence(&block)
|
159
|
-
|
164
|
+
enumerate_occurrences(start_time, &block).to_a
|
160
165
|
self
|
161
166
|
end
|
162
167
|
|
163
168
|
# The next n occurrences after now
|
164
169
|
def next_occurrences(num, from = nil)
|
165
170
|
from ||= TimeUtil.now(@start_time)
|
166
|
-
|
171
|
+
enumerate_occurrences(from + 1, nil).take(num)
|
167
172
|
end
|
168
173
|
|
169
174
|
# The next occurrence after now (overridable)
|
170
175
|
def next_occurrence(from = nil)
|
171
176
|
from ||= TimeUtil.now(@start_time)
|
172
|
-
|
177
|
+
enumerate_occurrences(from + 1, nil).next()
|
173
178
|
end
|
174
179
|
|
175
180
|
# The previous occurrence from a given time
|
176
181
|
def previous_occurrence(from)
|
177
182
|
return nil if from <= start_time
|
178
|
-
|
183
|
+
enumerate_occurrences(start_time, from - 1).to_a.last
|
179
184
|
end
|
180
185
|
|
181
186
|
# The previous n occurrences before a given time
|
182
187
|
def previous_occurrences(num, from)
|
183
188
|
return [] if from <= start_time
|
184
|
-
|
189
|
+
a = enumerate_occurrences(start_time, from - 1).to_a
|
190
|
+
a.size > num ? a[-1*num,a.size] : a
|
185
191
|
end
|
186
192
|
|
187
193
|
# The remaining occurrences (same requirements as all_occurrences)
|
188
194
|
def remaining_occurrences(from = nil)
|
189
195
|
require_terminating_rules
|
190
196
|
from ||= TimeUtil.now(@start_time)
|
191
|
-
|
197
|
+
enumerate_occurrences(from).to_a
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns an enumerator for all remaining occurrences
|
201
|
+
def remaining_occurrences_enumerator(from = nil)
|
202
|
+
from ||= TimeUtil.now(@start_time)
|
203
|
+
enumerate_occurrences(from)
|
192
204
|
end
|
193
205
|
|
194
206
|
# Occurrences between two times
|
195
207
|
def occurrences_between(begin_time, closing_time)
|
196
|
-
|
208
|
+
enumerate_occurrences(begin_time, closing_time).to_a
|
197
209
|
end
|
198
210
|
|
199
211
|
# Return a boolean indicating if an occurrence falls between two times
|
200
212
|
def occurs_between?(begin_time, closing_time)
|
201
|
-
|
213
|
+
begin
|
214
|
+
enumerate_occurrences(begin_time, closing_time).next()
|
215
|
+
true
|
216
|
+
rescue StopIteration
|
217
|
+
false
|
218
|
+
end
|
219
|
+
|
202
220
|
end
|
203
221
|
|
204
222
|
# Return a boolean indicating if an occurrence is occurring between two
|
@@ -247,6 +265,7 @@ module IceCube
|
|
247
265
|
end
|
248
266
|
# Go through each occurrence of the terminating schedule and determine
|
249
267
|
# if the other occurs at that time
|
268
|
+
#
|
250
269
|
last_time = nil
|
251
270
|
terminating_schedule.each_occurrence do |time|
|
252
271
|
if closing_time && time > closing_time
|
@@ -276,7 +295,7 @@ module IceCube
|
|
276
295
|
|
277
296
|
# Get the first n occurrences, or the first occurrence if n is skipped
|
278
297
|
def first(n = nil)
|
279
|
-
occurrences =
|
298
|
+
occurrences = enumerate_occurrences(start_time).take(n || 1)
|
280
299
|
n.nil? ? occurrences.first : occurrences
|
281
300
|
end
|
282
301
|
|
@@ -284,7 +303,7 @@ module IceCube
|
|
284
303
|
# or the final one if no n is given
|
285
304
|
def last(n = nil)
|
286
305
|
require_terminating_rules
|
287
|
-
occurrences =
|
306
|
+
occurrences = enumerate_occurrences(start_time).to_a
|
288
307
|
n.nil? ? occurrences.last : occurrences[-n..-1]
|
289
308
|
end
|
290
309
|
|
@@ -391,30 +410,27 @@ module IceCube
|
|
391
410
|
|
392
411
|
# Find all of the occurrences for the schedule between opening_time
|
393
412
|
# and closing_time
|
394
|
-
def
|
413
|
+
def enumerate_occurrences(opening_time, closing_time = nil, &block)
|
395
414
|
opening_time = TimeUtil.ensure_time opening_time
|
396
415
|
closing_time = TimeUtil.ensure_time closing_time
|
397
416
|
opening_time += start_time.subsec - opening_time.subsec rescue 0
|
398
417
|
reset
|
399
|
-
answers = []
|
400
418
|
opening_time = start_time if opening_time < start_time
|
401
419
|
# walk up to the opening time - and off we go
|
402
420
|
# If we have rules with counts, we need to walk from the beginning of time,
|
403
421
|
# otherwise opening_time
|
404
422
|
time = full_required? ? start_time : opening_time
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
423
|
+
e = Enumerator.new do |yielder|
|
424
|
+
loop do
|
425
|
+
res = next_time(time, closing_time)
|
426
|
+
break unless res
|
427
|
+
break if closing_time && res > closing_time
|
428
|
+
if res >= opening_time
|
429
|
+
yielder.yield (block_given? ? block.call(res) : res)
|
430
|
+
end
|
431
|
+
time = res + 1
|
413
432
|
end
|
414
|
-
time = res + 1
|
415
433
|
end
|
416
|
-
# and return our answers
|
417
|
-
answers
|
418
434
|
end
|
419
435
|
|
420
436
|
# Get the next time after (or including) a specific time
|
data/lib/ice_cube/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -9,6 +9,7 @@ require File.dirname(__FILE__) + '/../lib/ice_cube'
|
|
9
9
|
|
10
10
|
DAY = Time.utc(2010, 3, 1)
|
11
11
|
WEDNESDAY = Time.utc(2010, 6, 23, 5, 0, 0)
|
12
|
+
|
12
13
|
WORLD_TIME_ZONES = [
|
13
14
|
'America/Anchorage', # -1000 / -0900
|
14
15
|
'Europe/London', # +0000 / +0100
|
@@ -48,4 +49,5 @@ RSpec.configure do |config|
|
|
48
49
|
end
|
49
50
|
end
|
50
51
|
end
|
52
|
+
|
51
53
|
end
|
metadata
CHANGED
@@ -1,69 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ice_cube
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Crepezzi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 2.12.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 2.12.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: active_support
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 3.0.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 3.0.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: tzinfo
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
description: ice_cube is a recurring date library for Ruby. It allows for quick,
|
@@ -73,15 +73,14 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
+
- lib/ice_cube.rb
|
76
77
|
- lib/ice_cube/builders/hash_builder.rb
|
77
78
|
- lib/ice_cube/builders/ical_builder.rb
|
78
79
|
- lib/ice_cube/builders/string_builder.rb
|
79
80
|
- lib/ice_cube/deprecated.rb
|
80
|
-
- lib/ice_cube/enumerator.rb
|
81
81
|
- lib/ice_cube/errors/count_exceeded.rb
|
82
82
|
- lib/ice_cube/errors/until_exceeded.rb
|
83
83
|
- lib/ice_cube/flexible_hash.rb
|
84
|
-
- lib/ice_cube/hash_input.rb
|
85
84
|
- lib/ice_cube/occurrence.rb
|
86
85
|
- lib/ice_cube/rule.rb
|
87
86
|
- lib/ice_cube/rules/daily_rule.rb
|
@@ -93,8 +92,6 @@ files:
|
|
93
92
|
- lib/ice_cube/rules/yearly_rule.rb
|
94
93
|
- lib/ice_cube/schedule.rb
|
95
94
|
- lib/ice_cube/single_occurrence_rule.rb
|
96
|
-
- lib/ice_cube/string_helpers.rb
|
97
|
-
- lib/ice_cube/time_step.rb
|
98
95
|
- lib/ice_cube/time_util.rb
|
99
96
|
- lib/ice_cube/validated_rule.rb
|
100
97
|
- lib/ice_cube/validations/count.rb
|
@@ -117,7 +114,6 @@ files:
|
|
117
114
|
- lib/ice_cube/validations/weekly_interval.rb
|
118
115
|
- lib/ice_cube/validations/yearly_interval.rb
|
119
116
|
- lib/ice_cube/version.rb
|
120
|
-
- lib/ice_cube.rb
|
121
117
|
- spec/spec_helper.rb
|
122
118
|
homepage: http://seejohnrun.github.com/ice_cube/
|
123
119
|
licenses:
|
@@ -129,20 +125,19 @@ require_paths:
|
|
129
125
|
- lib
|
130
126
|
required_ruby_version: !ruby/object:Gem::Requirement
|
131
127
|
requirements:
|
132
|
-
- -
|
128
|
+
- - ">="
|
133
129
|
- !ruby/object:Gem::Version
|
134
130
|
version: '0'
|
135
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
132
|
requirements:
|
137
|
-
- -
|
133
|
+
- - ">="
|
138
134
|
- !ruby/object:Gem::Version
|
139
135
|
version: '0'
|
140
136
|
requirements: []
|
141
137
|
rubyforge_project: ice-cube
|
142
|
-
rubygems_version: 2.0
|
138
|
+
rubygems_version: 2.2.0
|
143
139
|
signing_key:
|
144
140
|
specification_version: 4
|
145
141
|
summary: Ruby Date Recurrence Library
|
146
142
|
test_files:
|
147
143
|
- spec/spec_helper.rb
|
148
|
-
has_rdoc: true
|
data/lib/ice_cube/enumerator.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
module IceCube
|
2
|
-
class Enumerator < ::Enumerator
|
3
|
-
|
4
|
-
def initialize(schedule, from_time, to_time)
|
5
|
-
@schedule = schedule
|
6
|
-
@from_time = TimeUtil.ensure_time(from_time)
|
7
|
-
@to_time = TimeUtil.ensure_time(to_time)
|
8
|
-
align_start_time
|
9
|
-
@cursor = @from_time
|
10
|
-
end
|
11
|
-
|
12
|
-
def each
|
13
|
-
while res = self.find_next && @to_time.nil? || res <= @to_time
|
14
|
-
yield Occurrence.new(res, res + schedule.duration)
|
15
|
-
end
|
16
|
-
raise StopIteration
|
17
|
-
end
|
18
|
-
|
19
|
-
def find_next
|
20
|
-
loop do
|
21
|
-
min_time = recurrence_rules.reduce(nil) do |min_time, rule|
|
22
|
-
catch :limit do
|
23
|
-
new_time = rule.next_time(time, schedule, min_time || @to_time)
|
24
|
-
[min_time, new_time].compact.min
|
25
|
-
end
|
26
|
-
end
|
27
|
-
break nil unless min_time
|
28
|
-
@cursor = min_time + 1
|
29
|
-
next if exception_time?(min_time)
|
30
|
-
break min_time
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def align_start_time
|
37
|
-
if @from_time <= schedule.start_time || full_required?
|
38
|
-
@from_time = schedule.start_time
|
39
|
-
else
|
40
|
-
@from_time += @schedule.start_time.subsec - @from_time.subsec rescue 0
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Return a boolean indicating if any rule needs to be run from the start of time
|
45
|
-
def full_required?
|
46
|
-
recurrence_rules.any?(&:full_required?) ||
|
47
|
-
exception_rules.any?(&:full_required?)
|
48
|
-
end
|
49
|
-
|
50
|
-
def exception_rules
|
51
|
-
schedule.instance_variable_get(:@all_exception_rules)
|
52
|
-
end
|
53
|
-
|
54
|
-
def recurrence_rules
|
55
|
-
@recurrence_rules ||= if recurrence_rules.empty?
|
56
|
-
[SingleOccurrenceRule.new(schedule.start_time)].concat schedule.instance_variable_get(:@all_recurrence_rules)
|
57
|
-
else
|
58
|
-
schedule.instance_variable_get(:@all_recurrence_rules)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
data/lib/ice_cube/hash_input.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
module IceCube
|
2
|
-
class HashInput
|
3
|
-
|
4
|
-
class Mash
|
5
|
-
def initialize(hash)
|
6
|
-
@hash = hash
|
7
|
-
end
|
8
|
-
|
9
|
-
# Fetch values indifferently by symbol or string key without symbolizing
|
10
|
-
# arbitrary string input
|
11
|
-
#
|
12
|
-
def [](key)
|
13
|
-
@hash.fetch(key) do |key|
|
14
|
-
str_key = key.to_s
|
15
|
-
@hash.each_pair.detect do |sym_key, value|
|
16
|
-
return value if sym_key.to_s == str_key
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize(hash)
|
23
|
-
@input = Mash.new(hash)
|
24
|
-
end
|
25
|
-
|
26
|
-
def [](key)
|
27
|
-
@input[key]
|
28
|
-
end
|
29
|
-
|
30
|
-
def to_rule
|
31
|
-
return nil unless rule_class
|
32
|
-
rule = rule_class.new(interval, week_start)
|
33
|
-
rule.until(limit_time) if limit_time
|
34
|
-
rule.count(limit_count) if limit_count
|
35
|
-
validations.each do |validation, args|
|
36
|
-
rule.send(validation, *args)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def rule_class
|
41
|
-
return @rule_class if @rule_class
|
42
|
-
match = @input[:rule_type].match(/::(\w+Rule)$/)
|
43
|
-
@rule_class = IceCube.const_get(match[1]) if match
|
44
|
-
end
|
45
|
-
|
46
|
-
def interval
|
47
|
-
@input[:interval] || 1
|
48
|
-
end
|
49
|
-
|
50
|
-
def week_start
|
51
|
-
@input[:week_start] || :sunday
|
52
|
-
end
|
53
|
-
|
54
|
-
def limit_time
|
55
|
-
@limit_time ||= TimeUtil.deserialize_time(@input[:until])
|
56
|
-
end
|
57
|
-
|
58
|
-
def limit_count
|
59
|
-
@input[:count]
|
60
|
-
end
|
61
|
-
|
62
|
-
def validations
|
63
|
-
input_validations = Mash.new(@input[:validations] || {})
|
64
|
-
ValidatedRule::VALIDATION_ORDER.each_with_object({}) do |key, output_validations|
|
65
|
-
args = input_validations[key]
|
66
|
-
output_validations[key] = Array(args) if args
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
end
|
data/lib/ice_cube/time_step.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
module IceCube
|
2
|
-
class TimeStep
|
3
|
-
SECS = 1
|
4
|
-
MINS = 60
|
5
|
-
HOURS = MINS * 60
|
6
|
-
DAYS = HOURS * 24
|
7
|
-
WEEKS = DAYS * 7
|
8
|
-
MONTHS = {
|
9
|
-
1 => [ 28, 29, 30, 31].map { |m| m * DAYS },
|
10
|
-
2 => [ 59, 60, 61, 62].map { |m| m * DAYS },
|
11
|
-
3 => [ 89, 90, 91, 92].map { |m| m * DAYS },
|
12
|
-
4 => [120, 121, 122, 123].map { |m| m * DAYS },
|
13
|
-
5 => [150, 151, 152, 153].map { |m| m * DAYS },
|
14
|
-
6 => [181, 182, 183, 184].map { |m| m * DAYS },
|
15
|
-
7 => [212, 213, 214, 215].map { |m| m * DAYS },
|
16
|
-
8 => [242, 243, 244, 245].map { |m| m * DAYS },
|
17
|
-
9 => [273, 274, 275, 276].map { |m| m * DAYS },
|
18
|
-
10 => [303, 304, 305, 306].map { |m| m * DAYS },
|
19
|
-
11 => [334, 335, 336, 337].map { |m| m * DAYS },
|
20
|
-
12 => [365, 366] .map { |m| m * DAYS }
|
21
|
-
}
|
22
|
-
YEARS = [365, 366]
|
23
|
-
|
24
|
-
def next(base, validations)
|
25
|
-
end
|
26
|
-
|
27
|
-
def prev(base, validations)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|