time_range 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []