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.
- checksums.yaml +7 -0
- data/lib/time_range.rb +128 -0
- 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: []
|