time_chunk 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +102 -0
- data/VERSION +1 -1
- data/lib/time_chunk.rb +28 -5
- data/spec/time_chunk_spec.rb +53 -9
- data/time_chunk.gemspec +4 -4
- metadata +5 -5
- data/README.rdoc +0 -19
data/README.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# time_chunk
|
2
|
+
|
3
|
+
Iterate over a time range in discrete chunks.
|
4
|
+
|
5
|
+
## examples
|
6
|
+
|
7
|
+
### Enumerate each hour in a day.
|
8
|
+
```ruby
|
9
|
+
TimeChunk.each_hour('2013-05-15T00:00:00Z'..'2013-05-15T05:59:59Z') do |range|
|
10
|
+
puts range.inspect
|
11
|
+
end
|
12
|
+
```
|
13
|
+
|
14
|
+
Strings are parsed into `Time` instances automatically.
|
15
|
+
|
16
|
+
```
|
17
|
+
2013-05-15 00:00:00 UTC..2013-05-15 00:59:59 UTC
|
18
|
+
2013-05-15 01:00:00 UTC..2013-05-15 01:59:59 UTC
|
19
|
+
2013-05-15 02:00:00 UTC..2013-05-15 02:59:59 UTC
|
20
|
+
2013-05-15 03:00:00 UTC..2013-05-15 03:59:59 UTC
|
21
|
+
2013-05-15 04:00:00 UTC..2013-05-15 04:59:59 UTC
|
22
|
+
2013-05-15 05:00:00 UTC..2013-05-15 05:59:59 UTC
|
23
|
+
```
|
24
|
+
|
25
|
+
### Enumerate a range of days.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
TimeChunk.each_day('2013-05-15T00:00:00Z'..'2013-05-20T23:59:59Z') do |range|
|
29
|
+
puts range.inspect
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
```
|
34
|
+
2013-05-15 00:00:00 UTC..2013-05-15 23:59:59 UTC
|
35
|
+
2013-05-16 00:00:00 UTC..2013-05-16 23:59:59 UTC
|
36
|
+
2013-05-17 00:00:00 UTC..2013-05-17 23:59:59 UTC
|
37
|
+
2013-05-18 00:00:00 UTC..2013-05-18 23:59:59 UTC
|
38
|
+
2013-05-19 00:00:00 UTC..2013-05-19 23:59:59 UTC
|
39
|
+
2013-05-20 00:00:00 UTC..2013-05-20 23:59:59 UTC
|
40
|
+
```
|
41
|
+
|
42
|
+
If you supply a range of `Date`s instead of `Time` instances or strings,
|
43
|
+
`each_day` will yield `Date` instances instead of a time range.
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
start = Date.parse '2013-05-15'
|
47
|
+
finish = Date.parse '2013-05-20'
|
48
|
+
TimeChunk.each_day(start..finish) do |d|
|
49
|
+
puts d.to_s
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
```
|
54
|
+
2013-05-15
|
55
|
+
2013-05-16
|
56
|
+
2013-05-17
|
57
|
+
2013-05-18
|
58
|
+
2013-05-19
|
59
|
+
2013-05-20
|
60
|
+
```
|
61
|
+
|
62
|
+
|
63
|
+
### Enumerate using any chunk of time
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
TimeChunk.iterate('2013-05-15T00:00:00Z'..'2013-05-15T23:59:59Z', 6.hours) do |range|
|
67
|
+
puts range.inspect
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
```
|
72
|
+
2013-05-15 00:00:00 UTC..2013-05-15 05:59:59 UTC
|
73
|
+
2013-05-15 06:00:00 UTC..2013-05-15 11:59:59 UTC
|
74
|
+
2013-05-15 12:00:00 UTC..2013-05-15 17:59:59 UTC
|
75
|
+
2013-05-15 18:00:00 UTC..2013-05-15 23:59:59 UTC
|
76
|
+
```
|
77
|
+
|
78
|
+
This example uses the `6.hours` convenience method from `ActiveSupport`, but you
|
79
|
+
can supply any number of seconds.
|
80
|
+
|
81
|
+
### Enumerate using any chunk of days
|
82
|
+
|
83
|
+
`iterate_days` is the same as `iterate` except that the step size is specified
|
84
|
+
in days instead of seconds.
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
start = Date.parse '2013-05-01'
|
88
|
+
finish = Date.parse '2013-05-31'
|
89
|
+
TimeChunk.iterate_days(start..finish, 5) do |range|
|
90
|
+
puts "#{range.begin.to_s} .. #{range.end.to_s}"
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
```
|
95
|
+
2013-05-01 .. 2013-05-05
|
96
|
+
2013-05-06 .. 2013-05-10
|
97
|
+
2013-05-11 .. 2013-05-15
|
98
|
+
2013-05-16 .. 2013-05-20
|
99
|
+
2013-05-21 .. 2013-05-25
|
100
|
+
2013-05-26 .. 2013-05-30
|
101
|
+
2013-05-31 .. 2013-05-31
|
102
|
+
```
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.0.0
|
data/lib/time_chunk.rb
CHANGED
@@ -2,20 +2,33 @@ require 'time'
|
|
2
2
|
|
3
3
|
module TimeChunk
|
4
4
|
|
5
|
-
def self.
|
5
|
+
def self.each_minute(range)
|
6
6
|
# &Proc.new : return a proc containing the block passed to the method
|
7
7
|
# http://www.ruby-doc.org/core-1.9.3/Proc.html#method-c-new
|
8
|
-
iterate(range,
|
8
|
+
iterate(range, 60, &Proc.new)
|
9
9
|
end
|
10
10
|
|
11
11
|
def self.each_hour(range)
|
12
12
|
iterate(range, 3600, &Proc.new)
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.
|
16
|
-
|
15
|
+
def self.each_day(range)
|
16
|
+
# if we're given a date range, yield individual dates instead of a range.
|
17
|
+
if range.begin.is_a?(Date)
|
18
|
+
iterate(range, 86400) {|chunk| yield chunk.begin }
|
19
|
+
# otherwise yield a range like all other methods do.
|
20
|
+
else
|
21
|
+
iterate(range, 86400, &Proc.new)
|
22
|
+
end
|
17
23
|
end
|
18
24
|
|
25
|
+
# Iterate over any date or time range, yielding a range of no more than
|
26
|
+
# step_size duration (in seconds.) The final yielded range may be smaller than
|
27
|
+
# step_size if the total range is not a perfect multiple of the step_size.
|
28
|
+
#
|
29
|
+
# String arguments will be parsed into Times, and yield Time ranges.
|
30
|
+
# Date ranges will yield Date ranges. Note that step_size is always in seconds
|
31
|
+
# even for date ranges. If this feels weird, see iterate_days instead.
|
19
32
|
def self.iterate(range, step_size)
|
20
33
|
if range.first.is_a?(Time)
|
21
34
|
begin_at = range.first
|
@@ -42,4 +55,14 @@ module TimeChunk
|
|
42
55
|
yield current_begin..current_end
|
43
56
|
end while current_end < end_at
|
44
57
|
end
|
45
|
-
|
58
|
+
|
59
|
+
# Same as iterate, but with step_size specified in days instead of seconds.
|
60
|
+
def self.iterate_days(range, step_size)
|
61
|
+
if ! range.begin.is_a?(Date) || ! range.end.is_a?(Date)
|
62
|
+
raise ArgumentError, "iterate_days requires a range of dates."
|
63
|
+
end
|
64
|
+
|
65
|
+
iterate(range, step_size*86400, &Proc.new)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/spec/time_chunk_spec.rb
CHANGED
@@ -105,17 +105,61 @@ describe TimeChunk do
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
|
109
|
-
|
110
|
-
|
108
|
+
describe "each_day" do
|
109
|
+
it "should yield time ranges when given string arguments" do
|
110
|
+
TimeChunk.each_day('2013-01-01T00:00:00Z'..'2013-01-04T23:59:59Z') do |range|
|
111
|
+
@calls << range
|
112
|
+
end
|
113
|
+
|
114
|
+
@calls.should eq [
|
115
|
+
(t('2013-01-01T00:00:00Z')..t('2013-01-01T23:59:59Z')),
|
116
|
+
(t('2013-01-02T00:00:00Z')..t('2013-01-02T23:59:59Z')),
|
117
|
+
(t('2013-01-03T00:00:00Z')..t('2013-01-03T23:59:59Z')),
|
118
|
+
(t('2013-01-04T00:00:00Z')..t('2013-01-04T23:59:59Z')),
|
119
|
+
]
|
111
120
|
end
|
112
121
|
|
113
|
-
|
114
|
-
(
|
115
|
-
(
|
116
|
-
|
117
|
-
(
|
118
|
-
|
122
|
+
it "should yield date instances when given date range arguments" do
|
123
|
+
start = Date.parse('2013-05-15')
|
124
|
+
finish = Date.parse('2013-05-20')
|
125
|
+
|
126
|
+
TimeChunk.each_day(start..finish) {|date| @calls << date}
|
127
|
+
|
128
|
+
expected = ["2013-05-15", "2013-05-16", "2013-05-17", "2013-05-18", "2013-05-19", "2013-05-20"]
|
129
|
+
@calls.map(&:to_s).should eq expected
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should raise an error if the start is after the finish" do
|
133
|
+
finish = Date.parse('2013-05-15')
|
134
|
+
start = Date.parse('2013-05-20')
|
135
|
+
|
136
|
+
expect {
|
137
|
+
TimeChunk.each_day(start..finish) {|date| @calls << date}
|
138
|
+
}.to raise_error ArgumentError, "Given range's begin (2013-05-20T05:00:00Z) is after its end (2013-05-15T05:00:00Z)."
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "iterate_days" do
|
144
|
+
it "should iterate in chunks of the given number of days" do
|
145
|
+
start = Date.parse('2013-05-01')
|
146
|
+
finish = Date.parse('2013-05-31')
|
147
|
+
|
148
|
+
TimeChunk.iterate_days(start..finish, 5) do |range|
|
149
|
+
@calls << [range.first.to_s, range.last.to_s]
|
150
|
+
end
|
151
|
+
|
152
|
+
expected = [
|
153
|
+
["2013-05-01", "2013-05-05"],
|
154
|
+
["2013-05-06", "2013-05-10"],
|
155
|
+
["2013-05-11", "2013-05-15"],
|
156
|
+
["2013-05-16", "2013-05-20"],
|
157
|
+
["2013-05-21", "2013-05-25"],
|
158
|
+
["2013-05-26", "2013-05-30"],
|
159
|
+
["2013-05-31", "2013-05-31"]
|
160
|
+
]
|
161
|
+
@calls.should eq expected
|
162
|
+
end
|
119
163
|
end
|
120
164
|
|
121
165
|
it "should iterate over each_hour" do
|
data/time_chunk.gemspec
CHANGED
@@ -5,16 +5,16 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "time_chunk"
|
8
|
-
s.version = "
|
8
|
+
s.version = "1.0.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alex Dean"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-05-17"
|
13
13
|
s.description = "Iterate over time ranges in discrete chunks."
|
14
14
|
s.email = "alex@crackpot.org"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
|
-
"README.
|
17
|
+
"README.md"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
"Gemfile",
|
23
23
|
"Gemfile.lock",
|
24
24
|
"LICENSE.txt",
|
25
|
-
"README.
|
25
|
+
"README.md",
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"lib/time_chunk.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: time_chunk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -81,14 +81,14 @@ executables: []
|
|
81
81
|
extensions: []
|
82
82
|
extra_rdoc_files:
|
83
83
|
- LICENSE.txt
|
84
|
-
- README.
|
84
|
+
- README.md
|
85
85
|
files:
|
86
86
|
- .document
|
87
87
|
- .rspec
|
88
88
|
- Gemfile
|
89
89
|
- Gemfile.lock
|
90
90
|
- LICENSE.txt
|
91
|
-
- README.
|
91
|
+
- README.md
|
92
92
|
- Rakefile
|
93
93
|
- VERSION
|
94
94
|
- lib/time_chunk.rb
|
@@ -110,7 +110,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
110
|
version: '0'
|
111
111
|
segments:
|
112
112
|
- 0
|
113
|
-
hash: -
|
113
|
+
hash: -197955871905249564
|
114
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
115
|
none: false
|
116
116
|
requirements:
|
data/README.rdoc
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
= time_chunk
|
2
|
-
|
3
|
-
Iterate over a time range in discrete chunks.
|
4
|
-
|
5
|
-
== Contributing to time_chunk
|
6
|
-
|
7
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
8
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
9
|
-
* Fork the project.
|
10
|
-
* Start a feature/bugfix branch.
|
11
|
-
* Commit and push until you are happy with your contribution.
|
12
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2013 Alex Dean. See LICENSE.txt for
|
18
|
-
further details.
|
19
|
-
|