ice_cube 0.11.1 → 0.11.2
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/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
|