timerage 1.8.0 → 2.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a516908d80d7444bc7558fe488fe546aba2d123f
4
- data.tar.gz: d3ca42c6b1190a24c9030f6e91cebb5844447c05
3
+ metadata.gz: f82bbd7083065080ca7d80bf905a6f77d8bf2e7f
4
+ data.tar.gz: fbbcc51556bbdcf68e000937cb0d219c78f942e1
5
5
  SHA512:
6
- metadata.gz: aca0bf8520121da781d8e28a0f80974d619feba6f1e1a2f6b15055ff83e09489fc138a8dabfb47b594b43b738650294ed63ad089f9c2630e17a4467fc3c874d4
7
- data.tar.gz: b73c86c3d951f1cd9571b63015647e67635d45a1cef8bec33d2794a213e08154765a0ea74575c7399a4e0dfd3522f5b0e651ef660b90624d0560233a25bfd6ba
6
+ metadata.gz: 0f3d81194d057830e4fe1743df1b8fe65c79af78ebf71f406792d1d26f513aac2f42321dea5cc58633c9733aa043321b091f96e6fc6244d99952b9bc81c8ea66
7
+ data.tar.gz: 04d3101baf65ab9eef0b4ffd3ccd7b6081016debe211e69cdf40c7f26395809f2efb29e66fbd785cbb94749da93fb5d2ae7a8cdcd9ec79f67b6865a1f9edb3d2
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Timerage
2
2
 
3
- Simple refinement to make Time Ranges work a little.
3
+ Time Ranges that are actually useful.
4
4
 
5
5
  ## Installation
6
6
 
@@ -20,15 +20,66 @@ Or install it yourself as:
20
20
 
21
21
  ```ruby
22
22
  require 'timerage'
23
+ ```
24
+
25
+ ### Coercion to Time (related) objects
26
+
27
+ ``` ruby
28
+ a_time = Timerage("2016-01-18T22:25:37Z")
29
+ # => 2016-01-18 22:25:37 +0000
30
+
31
+ Timerage(a_time)
32
+ # => 2016-01-18 22:25:37 +0000
33
+
34
+ Timerage("2016-01-18T21:25:37+00:00/2016-01-18T22:25:37+00:00")
35
+ # => 2016-01-18 21:25:37 +0000...2016-01-18 22:25:37 +0000
36
+
37
+ interval = Timerage((a_time-3600)...a_time)
38
+ # => 2016-01-18 21:25:37 +0000...2016-01-18 22:25:37 +0000
39
+ ```
23
40
 
24
- class MyClass
25
- using Timerage
41
+ ### Stepping over a time inteval
42
+
43
+ ```ruby
44
+ interval.step(30*60).map { |time| time }
45
+ # => [2016-01-18 21:25:37 +0000, 2016-01-18 21:55:37 +0000]
46
+ ```
47
+
48
+ ### Slicing a time interval
49
+
50
+ ```ruby
51
+ interval.slice(30*60).map { |time| time }
52
+ # => [2016-01-18 21:25:37 UTC...2016-01-18 21:55:37 UTC, 2016-01-18 21:55:37 UTC...2016-01-18 22:25:37 UTC]
53
+ ```
26
54
 
27
- # Step over these two times in 10 second steps
28
- def my_method(time1, time2)
29
- (time1..time2).step(10) { |time| puts time}
30
- end
31
- end
55
+ ### ISO 8601 output
56
+
57
+ ```ruby
58
+ interval.iso8601
59
+ # => "2016-01-18T21:25:37+00:00/2016-01-18T22:25:37+00:00"
60
+ ```
61
+
62
+ ### Comparisons
63
+
64
+ Supports most range/set comparisons
65
+
66
+ * `#overlap?`
67
+ * `#cover?`
68
+ * `#adjacent_to?`
69
+ * `#==`
70
+
71
+ ### Concatenation
72
+
73
+ ```ruby
74
+ interval + Timerage("2016-01-18T20:25:37+00:00/2016-01-18T21:25:37+00:00")
75
+ # => 2016-01-18 20:25:37 UTC..2016-01-18 22:25:37 UTC
76
+ ```
77
+
78
+ ### Duration
79
+
80
+ ```ruby
81
+ interval.duration
82
+ # => 3600.0
32
83
  ```
33
84
 
34
85
  ## Gotchas
@@ -10,8 +10,8 @@ module Timerage
10
10
  # --
11
11
  #
12
12
  # Currently this only supports `<begin>/<end>` style time intervals.
13
- def self.parse_iso8601(str)
14
- TimeInterval.iso8601(str)
13
+ def self.parse_iso8601(str, exclusive_end: true)
14
+ TimeInterval.iso8601(str, exclusive_end: exclusive_end)
15
15
  rescue ArgumentError
16
16
  Time.iso8601(str)
17
17
  end
@@ -30,3 +30,27 @@ module Timerage
30
30
  end
31
31
  end
32
32
  end
33
+
34
+ module Kernel
35
+ def Timerage(time_or_time_interval_ish)
36
+ thing = time_or_time_interval_ish
37
+
38
+ case thing
39
+ when ->(x) { x.respond_to? :to_time_interval }
40
+ thing
41
+
42
+ when ->(x) { x.respond_to? :exclude_end? }
43
+ Timerage::TimeInterval.new(thing)
44
+
45
+ when ->(x) { x.respond_to? :to_str }
46
+ Timerage.parse_iso8601(thing.to_str)
47
+
48
+ when ->(x) { x.respond_to? :to_time }
49
+ thing.to_time
50
+
51
+ else
52
+ fail TypeError, "unable to coerce #{thing} to a time or interval"
53
+
54
+ end
55
+ end
56
+ end
@@ -13,6 +13,10 @@ module Timerage
13
13
  super rng
14
14
  end
15
15
 
16
+ def to_time_interval
17
+ self
18
+ end
19
+
16
20
  alias_method :to_time, :begin
17
21
 
18
22
  # Returns number of seconds in this interval
@@ -53,37 +57,41 @@ module Timerage
53
57
  "#{self.begin.iso8601(*args)}/#{self.end.iso8601(*args)}"
54
58
  end
55
59
 
60
+ def getutc
61
+ return self if self.begin.utc? && self.end.utc?
62
+ self.class.new(self.begin.getutc, self.end.getutc, self.exclude_end?)
63
+ end
64
+
56
65
  def adjacent_to?(other)
57
66
  other.begin == self.end || other.end == self.begin
58
67
  end
59
68
 
60
69
  def cover?(time_or_interval)
61
- return super unless rangeish?(time_or_interval)
62
-
63
70
  other = time_or_interval
71
+ return super unless rangeish?(other)
72
+ return false unless overlap?(other)
64
73
 
65
- self.begin <= other.begin &&
66
- if self.exclude_end? && other.exclude_end?
67
- self.end > other.begin && self.begin < other.end && other.end <= self.end
68
-
69
- elsif self.exclude_end?
70
- self.end > other.begin && self.begin <= other.end && other.end < self.end
71
-
72
- elsif other.exclude_end?
73
- self.end >= other.begin && self.begin < other.end && other.end <= self.end
74
-
74
+ self_end, other_end = self.end, other.end
75
+ other.begin >= self.begin &&
76
+ if !self.exclude_end? || other.exclude_end?
77
+ other_end <= self_end
75
78
  else
76
- self.end >= other.begin && self.begin <= other.end && other.end <= self.end
79
+ other_end < self_end
77
80
  end
78
81
  end
79
82
 
80
83
  def overlap?(other)
81
- cover?(other) ||
82
- other.cover?(self) ||
83
- cover?(other.begin) ||
84
- other.cover?(self.begin) ||
85
- cover?(other.end) && (!other.exclude_end? || other.end != self.begin) ||
86
- other.cover?(self.end) && (!self.exclude_end? || other.begin != self.end)
84
+ earliest, latest = if self.begin <= other.begin
85
+ [self, other]
86
+ else
87
+ [other, self]
88
+ end
89
+
90
+ latest_begin, earliest_end = latest.begin, earliest.end
91
+ return true if latest_begin < earliest_end
92
+ return false if earliest_end < latest_begin
93
+
94
+ !earliest.exclude_end?
87
95
  end
88
96
 
89
97
  def <=>(other)
@@ -159,11 +167,12 @@ module Timerage
159
167
  # --
160
168
  #
161
169
  # Currently this only supports `<begin>/<end>` style time intervals.
162
- def self.iso8601(str)
163
- new *str.split("/").map{|s| Time.iso8601(s)}
170
+ def self.iso8601(str, exclusive_end: true)
171
+ new *str.split("/", 2).map{|s| Time.iso8601(s)}, exclusive_end
164
172
 
165
173
  rescue ArgumentError
166
174
  raise ArgumentError, "Invalid iso8601 interval: #{str.inspect}"
167
175
  end
168
176
  end
177
+
169
178
  end
@@ -1,3 +1,3 @@
1
1
  module Timerage
2
- VERSION = "1.8.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -19,6 +19,24 @@ describe Timerage::TimeInterval do
19
19
  .to raise_error ArgumentError }
20
20
  end
21
21
 
22
+ describe "#getutc" do
23
+ subject(:interval_utc) { described_class.new(now-duration, now).getutc }
24
+ specify { expect(interval_utc).to be_kind_of described_class }
25
+
26
+ context "interval not in utc" do
27
+ specify { expect(now).not_to be_utc }
28
+ specify { expect(interval_utc.begin).to be_utc }
29
+ specify { expect(interval_utc.end).to be_utc }
30
+ end
31
+
32
+ context "interval already in utc" do
33
+ let(:now) { Time.now.getutc }
34
+ specify { expect(now).to be_utc }
35
+ specify { expect(interval_utc.begin).to be_utc }
36
+ specify { expect(interval_utc.end).to be_utc }
37
+ end
38
+ end
39
+
22
40
  subject(:interval) { described_class.new(now-duration, now) }
23
41
 
24
42
  it { is_expected.to behave_like_a Range }
@@ -9,7 +9,7 @@ describe Timerage do
9
9
  specify { expect(range.to_time_interval).to be_kind_of Timerage::TimeInterval }
10
10
  specify { expect{|b| range.step(1200, &b) }.to yield_control.at_least(:once) }
11
11
 
12
- describe ".iso8601" do
12
+ describe ".parse_iso8601" do
13
13
  specify { expect(described_class
14
14
  .parse_iso8601("2001-01-01T00:00:00Z/2001-01-02T00:00:00-06:00"))
15
15
  .to be_kind_of Timerage::TimeInterval }
@@ -30,7 +30,23 @@ describe Timerage do
30
30
  .to yield_successive_args now-duration, now-(duration-1200), now-(duration-2400) }
31
31
  end
32
32
 
33
- let(:now) { Time.now }
33
+ describe "Kernel.Timerage" do
34
+ specify { expect( Timerage(a_time) ).to eq a_time }
35
+
36
+ specify { expect( Timerage(a_time_interval) ).to eq a_time_interval }
37
+ specify { expect( Timerage(a_range_of_times) ).to eq a_time_interval }
38
+
39
+ specify { expect( Timerage(a_time.iso8601(20)) ).to eq a_time }
40
+ specify { expect( Timerage(a_time_interval.iso8601(20)) ).to eq a_time_interval }
41
+
42
+ specify { expect{ Timerage(nil) }.to raise_error TypeError }
43
+ specify { expect{ Timerage(42) }.to raise_error TypeError }
44
+ end
45
+
46
+ let(:now) { Time.now.getutc }
47
+ let(:a_time) { now }
48
+ let(:a_time_interval) { Timerage::TimeInterval.new(now, now+duration, true) }
49
+ let(:a_range_of_times) { a_time_interval.begin...a_time_interval.end }
34
50
  let(:duration) { 3600 }
35
51
  end
36
52
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timerage
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Williams
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-09-03 00:00:00.000000000 Z
12
+ date: 2016-01-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
98
  version: '0'
99
99
  requirements: []
100
100
  rubyforge_project:
101
- rubygems_version: 2.2.2
101
+ rubygems_version: 2.4.5
102
102
  signing_key:
103
103
  specification_version: 4
104
104
  summary: Simple refinement to Range to allow Time or Date as arguments
@@ -106,4 +106,3 @@ test_files:
106
106
  - spec/spec_helper.rb
107
107
  - spec/timerage/time_interval_spec.rb
108
108
  - spec/timerage_spec.rb
109
- has_rdoc: