time_ext 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/README.md +38 -4
- data/VERSION +1 -1
- data/lib/time_ext/{time.rb → core_ext/time/calculations.rb} +17 -2
- data/lib/time_ext/core_ext/time/iterations.rb +79 -0
- data/lib/time_ext/method_chain.rb +18 -0
- data/lib/time_ext.rb +11 -1
- data/spec/{time_ext_spec.rb → time_calculations_spec.rb} +1 -1
- data/spec/time_iterations_spec.rb +69 -0
- metadata +11 -22
- data/doc/Time.html +0 -2277
- data/doc/_index.html +0 -94
- data/doc/class_list.html +0 -36
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -50
- data/doc/css/style.css +0 -277
- data/doc/file.README.html +0 -105
- data/doc/file_list.html +0 -38
- data/doc/frames.html +0 -13
- data/doc/index.html +0 -105
- data/doc/js/app.js +0 -138
- data/doc/js/full_list.js +0 -117
- data/doc/js/jquery.js +0 -19
- data/doc/method_list.html +0 -291
- data/doc/top-level-namespace.html +0 -88
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -10,20 +10,54 @@ This gem extends the abilities of Ruby's built-in Time class by building on top
|
|
10
10
|
|
11
11
|
## Basic Usage
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
### Pure Ruby
|
14
|
+
|
15
|
+
require "time/ext" # or "time_ext"
|
16
|
+
Time.utc(2010, 6, 19).round(:month) #=> Thu Jul 01 00:00:00 UTC 2010
|
15
17
|
#=> Beginning of this week, or next week depending on which date is closest
|
18
|
+
Time.now.each_hour.until(6.hours.from_now) { |t| puts t.to_s }
|
19
|
+
#=> Prints the time at one hour interals from now till 6 hours from now
|
20
|
+
|
21
|
+
### Rails 2.x
|
22
|
+
|
23
|
+
config.gem "time_ext"
|
24
|
+
|
25
|
+
### Rails 3.x
|
26
|
+
|
27
|
+
gem "time_ext"
|
16
28
|
|
17
29
|
|
18
30
|
## Documentation
|
19
31
|
|
20
|
-
|
32
|
+
Complete class and method documentation is available [here][docs] on [rdoc.info][].
|
33
|
+
|
34
|
+
### Calculations
|
35
|
+
|
36
|
+
ActiveSupport includes some handy `#beginning_of_*` and `#end_of_*` methods among others for year, month, week, and day. TimeExt adds the same methods for quarter (3 months), hour, minute, and second. Additionally it also adds a set of familiar math methods, `#floor`, `#ceil`, and `#round`. Each of them takes a unit argument (day, month, etc.), and goes about it's operation to that unit type.
|
37
|
+
|
38
|
+
### Iterations
|
39
|
+
|
40
|
+
You can easily iterate over specific units of time with the `#each`, `#beginning_of_each`, `#map_each`, and `#map_beginning_of_each` methods. Each method takes a unit input, just like the `#floor` method for example. But the iteration methods also have dynamic unit methods, like so:
|
41
|
+
|
42
|
+
time = Time.local(2010, 07, 10)
|
43
|
+
time.map_each(:hour).until(time + 6.hours) { |t| t.hour } #=> [1, 2, 3, 4, 5, 6]
|
44
|
+
time.map_each_hour.until(time + 6.hours) { |t| t.hour } #=> [1, 2, 3, 4, 5, 6]
|
45
|
+
|
46
|
+
The `#until` method defines when to stop the iteration. You can also use the `#from` method, which then iterates from the time passed into `#from` till the time of the object you're calling each on. If don't specify a end/start time, it'll assume you want all units within it's scope. Or in less gibberish, calling `#each_hour` will iterate every hour for a whole day, or 24 hours. If you're iterating by the minute, it'll stop after an hour.
|
47
|
+
|
48
|
+
Here's a couple of more examples:
|
49
|
+
|
50
|
+
time.map_each_hour.until(time + 6.hours) { |t| t.hour } #=> [1, 2, 3, 4, 5, 6]
|
51
|
+
time.until(time + 6.hours).map_each_hour { |t| t.hour } #=> [1, 2, 3, 4, 5, 6]
|
52
|
+
(time + 6.hours).map_each_hour.from(time) { |t| t.hour } #=> [1, 2, 3, 4, 5, 6]
|
53
|
+
(time + 6.hours).from(time).map_each_hour { |t| t.hour } #=> [1, 2, 3, 4, 5, 6]
|
21
54
|
|
22
|
-
|
55
|
+
I recommend you read the complete class [documentation][docs] for the Time object to see all the new methods available.
|
23
56
|
|
24
57
|
|
25
58
|
## To-Do
|
26
59
|
|
60
|
+
* Some cleaner code.
|
27
61
|
* Improve ReadMe file.
|
28
62
|
* Improve documentation.
|
29
63
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -32,15 +32,25 @@ class Time
|
|
32
32
|
end
|
33
33
|
alias :beginning_of_closest :round
|
34
34
|
|
35
|
+
# Returns a new Time representing the previoius unit specified (defaults to second).
|
36
|
+
def prev(unit = :sec)
|
37
|
+
send("prev_#{unit}")
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns a new Time representing the next unit specified (defaults to second).
|
41
|
+
def next(unit = :sec)
|
42
|
+
send("next_#{unit}")
|
43
|
+
end
|
44
|
+
|
35
45
|
# Short-hand for seconds_ago(1).
|
36
46
|
def prev_second
|
37
|
-
|
47
|
+
seconds_ago(1)
|
38
48
|
end
|
39
49
|
alias :prev_sec :prev_second
|
40
50
|
|
41
51
|
# Short-hand for seconds_since(1).
|
42
52
|
def next_second
|
43
|
-
|
53
|
+
seconds_since(1)
|
44
54
|
end
|
45
55
|
alias :next_sec :next_second
|
46
56
|
|
@@ -149,6 +159,11 @@ class Time
|
|
149
159
|
since((quarters * 3).months)
|
150
160
|
end
|
151
161
|
|
162
|
+
# Returns a new Time representing the end of the unit specified (defaults to second).
|
163
|
+
def end_of(unit = :sec)
|
164
|
+
send("end_of_#{unit}")
|
165
|
+
end
|
166
|
+
|
152
167
|
# Returns a new Time representing the start of the second, XX:XX:XX.000000 (.000000000 in ruby1.9).
|
153
168
|
def beginning_of_second
|
154
169
|
change(:usec => 0)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
class Time
|
2
|
+
include TimeExt::MethodChain
|
3
|
+
|
4
|
+
# Used by #each, #map_each and similar methods to iterate over ranges of time.
|
5
|
+
def iterate(unit, options = {}, &block)
|
6
|
+
options.reverse_merge!(:map_result => false, :beginning_of => false, :include_start => false)
|
7
|
+
if block_given?
|
8
|
+
units = [:year, :month, :day, :hour, :min, :sec, :usec]
|
9
|
+
parent_unit = units[units.index(unit)-1]
|
10
|
+
@until ||= (!parent_unit.nil?) ? self.send("#{parent_unit}s_since", 1) : self.send("#{unit}s_since", 1)
|
11
|
+
time = self.clone
|
12
|
+
direction = (self < @until) ? :f : :b
|
13
|
+
succ_method = (direction == :f) ? "next_#{unit}" : "prev_#{unit}"
|
14
|
+
time = time.beginning_of(unit) if options[:beginning_of]
|
15
|
+
time = time.send(succ_method) if !options[:include_start]
|
16
|
+
results = []
|
17
|
+
while (direction == :f && time <= @until) || (direction == :b && time >= @until)
|
18
|
+
options[:map_result] ? results << yield(time) : yield(time)
|
19
|
+
time = time.send(succ_method)
|
20
|
+
end
|
21
|
+
options[:map_result] ? results : self
|
22
|
+
else
|
23
|
+
add_to_chain(:iterate, unit, options)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Used togeter with #each and other iteration methods to specify end of interation.
|
29
|
+
def until(time, &block)
|
30
|
+
time = time.to_time if time.is_a?(::Date)
|
31
|
+
@until = time
|
32
|
+
return call_chain(block) if block_given?
|
33
|
+
self
|
34
|
+
end
|
35
|
+
alias :till :until
|
36
|
+
|
37
|
+
# Used together with #each and other interation methods to specify start of iteration, and end will be current object.
|
38
|
+
def from(time, &block)
|
39
|
+
time = time.to_time if time.is_a?(::Date)
|
40
|
+
method, args = @method_chain.pop if block_given?
|
41
|
+
if !method.nil?
|
42
|
+
time.until(self).send(method, *args, &block)
|
43
|
+
else
|
44
|
+
time.until(self)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Executes passed block for each "unit" of time specified, with a new time object for each interval passed to the block.
|
49
|
+
def each(unit, options = {}, &block)
|
50
|
+
iterate(unit, options.merge(:map_result => false), &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Executes passed block for each "unit" of time specified, with a new time object set to the beginning of "unit" for each interval passed to the block.
|
54
|
+
def beginning_of_each(unit, options = {}, &block)
|
55
|
+
iterate(unit, options.merge(:map_result => false, :beginning_of => true), &block)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Executes passed block for each "unit" of time specified, returning an array with the return values from the passed block.
|
59
|
+
def map_each(unit, options = {}, &block)
|
60
|
+
iterate(unit, options.merge(:map_result => true), &block)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Executes passed block for each "unit" of time specified, returning an array with the return values from passed block. Additionally the time object passed into the block is set to the beginning of specified "unit".
|
64
|
+
def map_beginning_of_each(unit, options = {}, &block)
|
65
|
+
iterate(unit, options.merge(:map_result => true, :beginning_of => true), &block)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Dynamically define convenience methods, like #each_hour instead of #each(:hour).
|
69
|
+
[:year, :month, :day, :hour, :min, :sec].each do |unit|
|
70
|
+
[:each, :beginning_of_each, :map_each, :map_beginning_of_each].each do |method|
|
71
|
+
define_method "#{method}_#{unit}" do |*args, &block|
|
72
|
+
send(method, unit, *args, &block)
|
73
|
+
end
|
74
|
+
class_eval { alias :"#{method}_minute" :"#{method}_min" } if unit == :min
|
75
|
+
class_eval { alias :"#{method}_second" :"#{method}_sec" } if unit == :sec
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module TimeExt
|
2
|
+
module MethodChain
|
3
|
+
|
4
|
+
def add_to_chain(method, *args, &block)
|
5
|
+
@method_chain ||= []
|
6
|
+
@method_chain << [method.to_sym, args, block]
|
7
|
+
end
|
8
|
+
|
9
|
+
def call_chain(custom_block = nil, &block)
|
10
|
+
method, args, iblock = @method_chain.pop
|
11
|
+
return nil if method.nil?
|
12
|
+
iblock = custom_block if !custom_block.nil?
|
13
|
+
method, args, iblock = yield(method, args, iblock) if block_given?
|
14
|
+
self.send(method, *args, &iblock)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/time_ext.rb
CHANGED
@@ -1,3 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'active_support'
|
3
|
-
require 'time_ext/
|
3
|
+
require 'time_ext/method_chain'
|
4
|
+
require 'time_ext/core_ext/time/calculations'
|
5
|
+
require 'time_ext/core_ext/time/iterations'
|
6
|
+
|
7
|
+
module TimeExt
|
8
|
+
|
9
|
+
module Base
|
10
|
+
TIME_EXT_UNITS = [:year, :month, :day, :hour, :min, :sec, :usec]
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Time Iterations" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@now = Time.now
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should iterate over time objects with #each" do
|
10
|
+
times = []
|
11
|
+
result = @now.each(:hour) { |time| times << time }
|
12
|
+
times.should have(24).items
|
13
|
+
times.should == (1..24).map { |i| @now + i.hours }
|
14
|
+
result.should == @now
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should iterate over time objects with #beginning_of_each" do
|
18
|
+
times = []
|
19
|
+
result = @now.beginning_of_each_hour { |time| times << time }
|
20
|
+
times.should have(24).items
|
21
|
+
times.should == (1..24).map { |i| @now.beginning_of_hour + i.hours }
|
22
|
+
result.should == @now
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should iterate over time objects with #map_each" do
|
26
|
+
result = @now.map_each_hour { |time| time }
|
27
|
+
result.should have(24).items
|
28
|
+
result.should == (1..24).map { |i| @now + i.hours }
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should iterate over time objects with #map_beginning_of_each" do
|
32
|
+
result = @now.map_beginning_of_each(:hour) { |time| time }
|
33
|
+
result.should have(24).items
|
34
|
+
result.should == (1..24).map { |i| @now.beginning_of_hour + i.hours }
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should iterate over time objects with #each and #until via method chaining" do
|
38
|
+
match = (1..6).map { |i| @now + i.hours }
|
39
|
+
|
40
|
+
times = []
|
41
|
+
result = @now.each(:hour).until(@now + 6.hours) { |time| times << time }
|
42
|
+
times.should == match
|
43
|
+
result.should == @now
|
44
|
+
|
45
|
+
times = []
|
46
|
+
result = @now.until(@now + 6.hours).each_hour { |time| times << time }
|
47
|
+
times.should == match
|
48
|
+
result.should == @now
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should iterate over time objects with #map_each and #until via method chaining" do
|
52
|
+
match = (1..6).map { |i| @now + i.hours }
|
53
|
+
@now.map_each_hour.until(@now + 6.hours) { |time| time }.should == match
|
54
|
+
@now.until(@now + 6.hours).map_each(:hour) { |time| time }.should == match
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should iterate over time objects backwards with #until set in the past" do
|
58
|
+
match = (1..6).map { |i| @now - i.hours }
|
59
|
+
@now.map_each_hour.until(@now - 6.hours) { |time| time }.should == match
|
60
|
+
@now.until(@now - 6.hours).map_each(:hour) { |time| time }.should == match
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should iterate over time objects with #map_each and #from via method chaining" do
|
64
|
+
match = (1..6).map { |i| @now + i.hours }
|
65
|
+
(@now + 6.hours).map_each_hour.from(@now) { |time| time }.should == match
|
66
|
+
(@now + 6.hours).from(@now).map_each(:hour) { |time| time }.should == match
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: time_ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jim Myhrberg
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-07-
|
18
|
+
date: 2010-07-29 00:00:00 +03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -80,27 +80,15 @@ files:
|
|
80
80
|
- README.md
|
81
81
|
- Rakefile
|
82
82
|
- VERSION
|
83
|
-
- doc/Time.html
|
84
|
-
- doc/_index.html
|
85
|
-
- doc/class_list.html
|
86
|
-
- doc/css/common.css
|
87
|
-
- doc/css/full_list.css
|
88
|
-
- doc/css/style.css
|
89
|
-
- doc/file.README.html
|
90
|
-
- doc/file_list.html
|
91
|
-
- doc/frames.html
|
92
|
-
- doc/index.html
|
93
|
-
- doc/js/app.js
|
94
|
-
- doc/js/full_list.js
|
95
|
-
- doc/js/jquery.js
|
96
|
-
- doc/method_list.html
|
97
|
-
- doc/top-level-namespace.html
|
98
83
|
- lib/time/ext.rb
|
99
84
|
- lib/time_ext.rb
|
100
|
-
- lib/time_ext/time.rb
|
85
|
+
- lib/time_ext/core_ext/time/calculations.rb
|
86
|
+
- lib/time_ext/core_ext/time/iterations.rb
|
87
|
+
- lib/time_ext/method_chain.rb
|
101
88
|
- spec/spec.opts
|
102
89
|
- spec/spec_helper.rb
|
103
|
-
- spec/
|
90
|
+
- spec/time_calculations_spec.rb
|
91
|
+
- spec/time_iterations_spec.rb
|
104
92
|
has_rdoc: true
|
105
93
|
homepage: http://github.com/jimeh/time_ext
|
106
94
|
licenses: []
|
@@ -137,4 +125,5 @@ specification_version: 3
|
|
137
125
|
summary: Extends the abilities of Ruby's built-in Time class by building on top of ActiveSupport.
|
138
126
|
test_files:
|
139
127
|
- spec/spec_helper.rb
|
140
|
-
- spec/
|
128
|
+
- spec/time_calculations_spec.rb
|
129
|
+
- spec/time_iterations_spec.rb
|