time_range 0.0.1

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/time_range.rb +128 -0
  3. metadata +43 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d90559eb4d0630208384e2daa03679dc45fb7399
4
+ data.tar.gz: 15b6b124c1dc63d1464c353dbeea8e7a2a7ff6d8
5
+ SHA512:
6
+ metadata.gz: 99e02e3ec2de2865b262ebef8417aeba44eb9972f373c1853046afe2fc5c015b3c7520ec8dc8ad2dfc14b50ab0ac9aff0cd62fb11dced1b3a22d168936cd211c
7
+ data.tar.gz: 9c31884bc13a23a723192ce4223f023d7f48d4dbd21bb5d85a980e6a6634112dfa76a09c2f3804484ff153a26ee45dcbc4d87cbc5682ffaadba5effeaf47a1d6
data/lib/time_range.rb ADDED
@@ -0,0 +1,128 @@
1
+
2
+ WRONG_ARG = "is not time"
3
+ # the TimeRange
4
+ #
5
+ # helps in Issues with time time ranges,
6
+ # such as intersecton of time ranges,
7
+ # union of time ranges, etc.
8
+ #
9
+ # == Examples
10
+ # require "time_range"
11
+ #
12
+ # range = TimeRange.new(Time.now - 1000, Time.now + 1000)
13
+ # # => 2013-09-13 23:32:16 +0400..2013-09-14 00:05:36 +0400
14
+ # today = TimeRange.for_date(Date.today)
15
+ # # => 2013-09-13 00:00:00 +0400..2013-09-13 23:59:59 +0400
16
+ #
17
+ # Check time presence in time range
18
+ # range.include?(Time.now)
19
+ # # => true
20
+ #
21
+ # Check time range presense in another time_range
22
+ # range2 = TimeRange.new(Time.now - 10, Time.now + 10)
23
+ # # => 2013-09-13 23:50:31 +0400..2013-09-13 23:50:51 +0400
24
+ #
25
+ # range.fully_include?(range2)
26
+ # # => true
27
+ #
28
+ # Check time ranges intersects each other:
29
+ # range.intersects?(range2)
30
+ # # => true
31
+ #
32
+ # Intersect time ranges
33
+ # range.intersection(range2)
34
+ # # => 2013-09-13 23:50:31 +0400..2013-09-13 23:50:51 +0400 # i.e equal range2
35
+ #
36
+ # Union time ranges
37
+ # range3 = TimeRange.new(Time.now + 10000, Time.now + 20000)
38
+ # TimeRange.union(range, range2, range3)
39
+ # # => [2013-09-13 23:32:16 +0400..2013-09-14 00:05:36 +0400,
40
+ # # 2013-09-14 02:41:17 +0400..2013-09-14 05:27:57 +0400]
41
+ #
42
+ # Subtract time ranges from one time range
43
+ # TimeRange.for_date(Date.today).subtract(TimeRange.new(Time.now + 900, Time.now + 1200),
44
+ # TimeRange.new(Time.now + 300, Time.now + 600))
45
+ # # => [2013-09-14 00:00:00 +0400..2013-09-14 00:55:51 +0400,
46
+ # # 2013-09-14 01:00:51 +0400..2013-09-14 01:05:51 +0400,
47
+ # # 2013-09-14 01:10:51 +0400..2013-09-14 23:59:59 +0400]
48
+ class TimeRange < Range
49
+
50
+ alias_method :orig_init, :initialize
51
+ def initialize(rbegin, rend)
52
+ raise WrongTimeRangeError, WRONG_ARG unless (rbegin.is_a?(Time) && rend.is_a?(Time))
53
+ rbegin, rend = rend, rbegin if rbegin > rend
54
+ orig_init(rbegin, rend)
55
+ end
56
+
57
+ def intersects?(range)
58
+ (self.begin >= range.begin && self.begin <= range.end) || (self.end >= range.begin && self.end <= range.end) ||
59
+ (range.begin >= self.begin && range.begin <= self.end) || (range.end >= self.begin && range.end <= self.end)
60
+ end
61
+
62
+ def intersection(range)
63
+ TimeRange.intersection(self, range)
64
+ end
65
+
66
+ def include?(time)
67
+ self.begin <= time && self.end >= time
68
+ end
69
+
70
+ def fully_include?(time_rage)
71
+ self.include?(time_rage.begin) && self.include?(time_rage.end)
72
+ end
73
+
74
+ def subtract(*ranges)
75
+ ranges = ranges.flatten.sort{|a, b| a.begin <=> b.begin}
76
+ return self if ranges.empty?
77
+ result = []
78
+ ranges.each do |range|
79
+ subtraction = self.intersection(TimeRange.new(self.begin, range.begin) ) if range.eql?(ranges.first)
80
+ result << subtraction if subtraction
81
+
82
+ if range.eql?(ranges.last)
83
+ subtraction = self.intersection(TimeRange.new(range.end, self.end ) )
84
+ result << subtraction if subtraction
85
+ else
86
+ subtraction = self.intersection(TimeRange.new(range.end, ranges[ranges.index(range) + 1].begin ))
87
+ result << subtraction if subtraction
88
+ end
89
+ end
90
+ TimeRange.union(result)
91
+ end
92
+
93
+ def self.for_date(date)
94
+ TimeRange.new(date.to_time, (date + 1).to_time - 1)
95
+ end
96
+
97
+ def self.intersection(*tranges)
98
+ return tranges if tranges.is_a?(TimeRange)
99
+ tranges = tranges.flatten.sort!{|a,b| a.begin <=> b.begin}
100
+ return tranges.first if (tranges.count == 1)
101
+ first, second = tranges[0], tranges[1]
102
+ if(tranges.count == 2)
103
+ return nil unless first.intersects?(second)
104
+ tbegin = [first.begin, second.begin].max
105
+ tend = [first.end, second.end].min
106
+ return TimeRange.new(tbegin, tend)
107
+ elsif tranges.count > 2
108
+ return intersection([intersection(first, second), tranges[2..-1] ].flatten) if first.intersects?(second)
109
+ end
110
+ end
111
+
112
+ def self.union(*tranges)
113
+ return tranges if tranges.is_a?(TimeRange) && tranges.begin != tranges.end
114
+ tranges = tranges.flatten.sort{|a,b| a.begin <=> b.begin}.select{|trange| trange.begin != trange.end}
115
+ return tranges.first if (tranges.count == 1)
116
+ first, second = tranges[0], tranges[1]
117
+ if(tranges.count == 2)
118
+ return [first, second] unless first.intersects?(second)
119
+ tbegin = [first.begin, second.begin].min
120
+ tend = [first.end, second.end].max
121
+ return TimeRange.new(tbegin, tend)
122
+ elsif tranges.count > 2
123
+ return [ first, union(tranges[1..-1])].flatten unless first.intersects?(second)
124
+ result = union([ union(first, second), tranges[2..-1]])
125
+ return result.is_a?(Array) ? result.flatten : result
126
+ end
127
+ end
128
+ end
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: time_range
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ilya Boltnev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-14 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Time ranges Intersection, union, etc
14
+ email: ilya@boltnev.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/time_range.rb
20
+ homepage: https://github.com/boltnev/time_ranges
21
+ licenses: []
22
+ metadata: {}
23
+ post_install_message:
24
+ rdoc_options: []
25
+ require_paths:
26
+ - lib
27
+ required_ruby_version: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ required_rubygems_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ requirements: []
38
+ rubyforge_project:
39
+ rubygems_version: 2.0.3
40
+ signing_key:
41
+ specification_version: 4
42
+ summary: The TimeRange class for help with some time range manipulations
43
+ test_files: []