time_spanner 1.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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +13 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +60 -0
  8. data/Rakefile +11 -0
  9. data/lib/time_spanner.rb +8 -0
  10. data/lib/time_spanner/duration_chain.rb +55 -0
  11. data/lib/time_spanner/errors.rb +8 -0
  12. data/lib/time_spanner/time_span.rb +34 -0
  13. data/lib/time_spanner/time_unit_collector.rb +59 -0
  14. data/lib/time_spanner/time_units.rb +17 -0
  15. data/lib/time_spanner/time_units/base/calendar_unit.rb +30 -0
  16. data/lib/time_spanner/time_units/base/time_unit.rb +39 -0
  17. data/lib/time_spanner/time_units/base/unit.rb +31 -0
  18. data/lib/time_spanner/time_units/century.rb +30 -0
  19. data/lib/time_spanner/time_units/day.rb +25 -0
  20. data/lib/time_spanner/time_units/decade.rb +25 -0
  21. data/lib/time_spanner/time_units/hour.rb +15 -0
  22. data/lib/time_spanner/time_units/microsecond.rb +15 -0
  23. data/lib/time_spanner/time_units/millennium.rb +25 -0
  24. data/lib/time_spanner/time_units/millisecond.rb +15 -0
  25. data/lib/time_spanner/time_units/minute.rb +15 -0
  26. data/lib/time_spanner/time_units/month.rb +25 -0
  27. data/lib/time_spanner/time_units/nanosecond.rb +15 -0
  28. data/lib/time_spanner/time_units/second.rb +15 -0
  29. data/lib/time_spanner/time_units/week.rb +25 -0
  30. data/lib/time_spanner/time_units/year.rb +25 -0
  31. data/lib/time_spanner/version.rb +3 -0
  32. data/test/test_helper.rb +9 -0
  33. data/test/time_spanner/duration_chain_test.rb +267 -0
  34. data/test/time_spanner/time_spanner_test.rb +27 -0
  35. data/test/time_spanner/time_unit_collector_test.rb +66 -0
  36. data/test/time_spanner/time_units/base/calendar_unit_test.rb +17 -0
  37. data/test/time_spanner/time_units/base/time_unit_test.rb +18 -0
  38. data/test/time_spanner/time_units/base/unit_test.rb +37 -0
  39. data/test/time_spanner/time_units/century_test.rb +55 -0
  40. data/test/time_spanner/time_units/day_test.rb +84 -0
  41. data/test/time_spanner/time_units/decade_test.rb +67 -0
  42. data/test/time_spanner/time_units/hour_test.rb +56 -0
  43. data/test/time_spanner/time_units/microsecond_test.rb +56 -0
  44. data/test/time_spanner/time_units/millennium_test.rb +69 -0
  45. data/test/time_spanner/time_units/millisecond_test.rb +56 -0
  46. data/test/time_spanner/time_units/minute_test.rb +84 -0
  47. data/test/time_spanner/time_units/month_test.rb +68 -0
  48. data/test/time_spanner/time_units/nanosecond_test.rb +40 -0
  49. data/test/time_spanner/time_units/second_test.rb +56 -0
  50. data/test/time_spanner/time_units/week_test.rb +55 -0
  51. data/test/time_spanner/time_units/year_test.rb +91 -0
  52. data/time_spanner.gemspec +23 -0
  53. metadata +143 -0
@@ -0,0 +1,25 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Day < CalendarUnit
5
+
6
+ def initialize
7
+ super 7
8
+ end
9
+
10
+
11
+ private
12
+
13
+ def calculate_amount
14
+ amount = ( to.to_time - from.to_time ).to_i / 86400
15
+ @amount = at_amount( amount ) > to ? amount - 1 : amount
16
+ end
17
+
18
+ def at_amount amount
19
+ ( from.to_datetime + amount ).to_time
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Decade < CalendarUnit
5
+
6
+ def initialize
7
+ super 3
8
+ end
9
+
10
+
11
+ private
12
+
13
+ def calculate_amount
14
+ amount = ( to.year - from.year ) / 10
15
+ @amount = at_amount( amount ) > to ? amount - 1 : amount
16
+ end
17
+
18
+ def at_amount amount
19
+ ( from.to_datetime >> amount * 120 ).to_time
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Hour < TimeUnit
5
+
6
+ MULTIPLIER = Rational 1, 3600
7
+
8
+ def initialize
9
+ super 8, MULTIPLIER
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Microsecond < TimeUnit
5
+
6
+ MULTIPLIER = 1000000
7
+
8
+ def initialize
9
+ super 12, MULTIPLIER
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Millennium < CalendarUnit
5
+
6
+ def initialize
7
+ super 1
8
+ end
9
+
10
+
11
+ private
12
+
13
+ def calculate_amount
14
+ amount = ( to.year - from.year ) / 1000
15
+ @amount = at_amount( amount ) > to ? amount - 1 : amount
16
+ end
17
+
18
+ def at_amount amount
19
+ ( from.to_datetime >> amount * 12000 ).to_time
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Millisecond < TimeUnit
5
+
6
+ MULTIPLIER = 1000
7
+
8
+ def initialize
9
+ super 11, MULTIPLIER
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Minute < TimeUnit
5
+
6
+ MULTIPLIER = Rational 1, 60
7
+
8
+ def initialize
9
+ super 9, MULTIPLIER
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Month < CalendarUnit
5
+
6
+ def initialize
7
+ super 5
8
+ end
9
+
10
+
11
+ private
12
+
13
+ def calculate_amount
14
+ amount = ( to.year * 12 + to.month ) - ( from.year * 12 + from.month ) - ( to.day < from.day ? 1 : 0 )
15
+ @amount = at_amount( amount ) > to ? amount - 1 : amount
16
+ end
17
+
18
+ def at_amount amount
19
+ ( from.to_datetime >> amount ).to_time
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Nanosecond < TimeUnit
5
+
6
+ MULTIPLIER = 1000000000
7
+
8
+ def initialize
9
+ super 13, MULTIPLIER
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Second < TimeUnit
5
+
6
+ MULTIPLIER = 1
7
+
8
+ def initialize
9
+ super 10, MULTIPLIER
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Week < CalendarUnit
5
+
6
+ def initialize
7
+ super 6
8
+ end
9
+
10
+
11
+ private
12
+
13
+ def calculate_amount
14
+ amount = ( ( to.to_datetime - from.to_datetime ) / 7 ).to_i
15
+ @amount = at_amount( amount ) > to ? amount - 1 : amount
16
+ end
17
+
18
+ def at_amount amount
19
+ ( from.to_datetime + amount * 7 ).to_time
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module TimeSpanner
2
+ module TimeUnits
3
+
4
+ class Year < CalendarUnit
5
+
6
+ def initialize
7
+ super 4
8
+ end
9
+
10
+
11
+ private
12
+
13
+ def calculate_amount
14
+ amount = to.year - from.year
15
+ @amount = at_amount( amount ) > to ? amount - 1 : amount
16
+ end
17
+
18
+ def at_amount amount
19
+ ( from.to_datetime >> amount * 12 ).to_time
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module TimeSpanner
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,9 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/spec'
3
+ require 'minitest/reporters'
4
+ require 'time_spanner'
5
+
6
+ MiniTest::Reporters.use!
7
+
8
+ class TestCase < Minitest::Spec
9
+ end
@@ -0,0 +1,267 @@
1
+ require 'test_helper'
2
+
3
+ module TimeSpanner
4
+
5
+ class DurationChainTest < TestCase
6
+ include TimeUnits
7
+
8
+ describe 'calculation by given units' do
9
+
10
+ before do
11
+ @from = Time.parse('2013-04-03 00:00:00')
12
+ @to = Time.parse('2013-04-03 02:12:37')
13
+ end
14
+
15
+ it 'initializes' do
16
+ chain = DurationChain.new(@from, @to, [])
17
+
18
+ assert_equal @to, chain.to
19
+ assert_equal 7957, chain.remaining
20
+ assert_equal [], chain.units
21
+ end
22
+
23
+ it 'should switch time span when target time is smaller than start time' do
24
+ from = Time.parse('2013-06-17 12:34:56')
25
+ to = Time.parse('2013-04-17 12:34:56')
26
+ chain = DurationChain.new(from, to, [])
27
+
28
+ assert_equal to, chain.instance_variable_get(:@from)
29
+ assert_equal from, chain.to
30
+ end
31
+
32
+ it 'sorts' do
33
+ chain = DurationChain.new(@from, @to, [Second, Hour, Minute])
34
+
35
+ assert chain.units.first.is_a?(Hour)
36
+ assert chain.units[1].is_a?(Minute)
37
+ assert chain.units.last.is_a?(Second)
38
+ end
39
+
40
+ it 'each calles for every unit' do
41
+ from = Time.at(DateTime.parse('2013-06-17 12:34:56').to_time, 2216234.383)
42
+ to = Time.at(DateTime.parse('5447-12-12 23:11:12').to_time, 3153476.737)
43
+ units = [Millennium, Century, Decade, Year, Month, Week, Day, Hour, Minute, Second, Millisecond, Microsecond, Nanosecond]
44
+ chain = DurationChain.new(from, to, units)
45
+
46
+ yielded = []
47
+ chain.each{|u| yielded << u}
48
+
49
+ assert_equal units.size, yielded.size
50
+ units.each do |unit|
51
+ assert_kind_of unit, yielded.shift
52
+ end
53
+ end
54
+
55
+ describe 'one unit given' do
56
+
57
+ it 'calculates hours' do
58
+ chain = DurationChain.new(@from, @to, [Hour])
59
+
60
+ assert_equal 2, chain.units.first.amount
61
+ end
62
+
63
+ it 'calculates minutes' do
64
+ chain = DurationChain.new(@from, @to, [Minute])
65
+
66
+ assert_equal 132, chain.units.first.amount
67
+ end
68
+
69
+ it 'calculates seconds' do
70
+ chain = DurationChain.new(@from, @to, [Second])
71
+
72
+ assert_equal 7957, chain.units.first.amount
73
+ end
74
+
75
+ end
76
+
77
+ describe 'two units given' do
78
+
79
+ it 'calculates hours and minutes' do
80
+ chain = DurationChain.new(@from, @to, [Hour, Minute])
81
+
82
+ assert_equal 2, chain.units.first.amount
83
+ assert_equal 12, chain.units.last.amount
84
+ end
85
+
86
+ it 'calculates minutes and seconds' do
87
+ chain = DurationChain.new(@from, @to, [Minute, Second])
88
+
89
+ assert_equal 132, chain.units.first.amount
90
+ assert_equal 37, chain.units.last.amount
91
+ end
92
+
93
+ it 'calculates hours and seconds' do
94
+ chain = DurationChain.new(@from, @to, [Second, Hour])
95
+
96
+ assert_equal 2, chain.units.first.amount
97
+ assert_equal 757, chain.units.last.amount
98
+ end
99
+
100
+ it 'calculates months and days' do
101
+ from = Time.parse('2013-04-01 00:00:00')
102
+ to = Time.parse('2013-07-19 00:00:00')
103
+ chain = DurationChain.new(from, to, [Month, Day])
104
+
105
+ assert_equal 3, chain.units.first.amount
106
+ assert_equal 18, chain.units.last.amount
107
+ end
108
+
109
+ it 'calculates months with microseconds' do
110
+ from = Time.parse('2013-04-01 00:00:00')
111
+ from_with_months = Time.parse('2013-08-01 00:00:00')
112
+ to = Time.at(from_with_months.to_f, 2.0)
113
+ chain = DurationChain.new(from, to, [Month, Microsecond])
114
+
115
+ assert_equal 4, chain.units.first.amount
116
+ assert_equal 2, chain.units.last.amount
117
+ end
118
+
119
+ it 'calculates years and months' do
120
+ from = Time.parse('2013-04-01 00:00:00')
121
+ to = Time.parse('2016-08-01 00:00:00')
122
+ chain = DurationChain.new(from, to, [Year, Month])
123
+
124
+ assert_equal 3, chain.units.first.amount
125
+ assert_equal 4, chain.units.last.amount
126
+ end
127
+
128
+ it 'calculates decades and years' do
129
+ from = Time.parse('2013-04-01 00:00:00')
130
+ to = Time.parse('2036-04-01 00:00:00')
131
+ chain = DurationChain.new(from, to, [Decade, Year])
132
+
133
+ assert_equal 2, chain.units.first.amount
134
+ assert_equal 3, chain.units.last.amount
135
+ end
136
+
137
+ it 'calculates centuries and years' do
138
+ from = Time.parse('2013-04-01 00:00:00')
139
+ to = Time.parse('2216-04-01 00:00:00')
140
+ chain = DurationChain.new(from, to, [Century, Year])
141
+
142
+ assert_equal 2, chain.units.first.amount
143
+ assert_equal 3, chain.units.last.amount
144
+ end
145
+
146
+ it 'calculates milleniums and nanoseconds' do
147
+ from = Time.parse('2013-04-01 00:00:00')
148
+ target_millenniums = Time.parse('4013-04-01 00:00:00')
149
+ to = Time.at(target_millenniums.to_r, 0.001)
150
+ chain = DurationChain.new(from, to, [Millennium, Nanosecond])
151
+
152
+ assert_equal 2, chain.units.first.amount
153
+ assert_equal 1, chain.units.last.amount
154
+ end
155
+
156
+ it 'calculates weeks and days' do
157
+ from = Time.parse('2013-04-01 00:00:00')
158
+ to = Time.parse('2013-04-26 00:00:00')
159
+ chain = DurationChain.new(from, to, [Week, Day])
160
+
161
+ assert_equal 3, chain.units.first.amount
162
+ assert_equal 4, chain.units.last.amount
163
+ end
164
+
165
+ end
166
+
167
+ describe 'three units given' do
168
+
169
+ it 'calculates hours, minutes and seconds' do
170
+ chain = DurationChain.new(@from, @to, [Hour, Minute, Second])
171
+
172
+ assert_equal 2, chain.units.first.amount
173
+ assert_equal 12, chain.units[1].amount
174
+ assert_equal 37, chain.units.last.amount
175
+ end
176
+
177
+ it 'calculates months, days and hours' do
178
+ from = Time.parse('2013-04-01 00:00:00')
179
+ to = Time.parse('2013-07-19 02:00:00')
180
+ chain = DurationChain.new(from, to, [Month, Day, Hour])
181
+
182
+ assert_equal 3, chain.units.first.amount
183
+ assert_equal 18, chain.units[1].amount
184
+ assert_equal 2, chain.units.last.amount
185
+ end
186
+
187
+ it 'calculates months, weeks and days' do
188
+ from = Time.parse('2013-04-01 00:00:00')
189
+ to = Time.parse('2013-07-19 02:00:00')
190
+ chain = DurationChain.new(from, to, [Month, Week, Day])
191
+
192
+ assert_equal 3, chain.units.first.amount
193
+ assert_equal 2, chain.units[1].amount
194
+ assert_equal 4, chain.units.last.amount
195
+ end
196
+
197
+ end
198
+
199
+ describe 'all units given' do
200
+
201
+ it 'calculates everything' do
202
+ from = Time.at(DateTime.parse('2013-06-17 12:34:56').to_time, 2216234.383)
203
+ to = Time.at(DateTime.parse('5447-12-12 23:11:12').to_time, 3153476.737)
204
+ chain = DurationChain.new(from, to, [Millennium, Century, Decade, Year, Month, Week, Day, Hour, Minute, Second, Millisecond, Microsecond, Nanosecond])
205
+
206
+ assert_equal 3, chain.units[0].amount
207
+ assert_equal 4, chain.units[1].amount
208
+ assert_equal 3, chain.units[2].amount
209
+ assert_equal 4, chain.units[3].amount
210
+ assert_equal 5, chain.units[4].amount
211
+ assert_equal 3, chain.units[5].amount
212
+ assert_equal 4, chain.units[6].amount
213
+ assert_equal 10, chain.units[7].amount
214
+ assert_equal 36, chain.units[8].amount
215
+ assert_equal 16, chain.units[9].amount
216
+ assert_equal 937, chain.units[10].amount
217
+ assert_equal 242, chain.units[11].amount
218
+ assert_equal 354, chain.units[12].amount
219
+ end
220
+
221
+ it 'calculates only some of them' do
222
+ from = Time.at(DateTime.parse('2013-07-28 00:00:01').to_time, 0.021)
223
+ to = Time.at(DateTime.parse('2014-08-01 00:00:59').to_time, 0.023)
224
+ chain = DurationChain.new(from, to, [Millennium, Century, Decade, Year, Month, Week, Day, Hour, Minute, Second, Millisecond, Microsecond, Nanosecond])
225
+
226
+ assert_equal 0, chain.units[0].amount
227
+ assert_equal 0, chain.units[1].amount
228
+ assert_equal 0, chain.units[2].amount
229
+ assert_equal 1, chain.units[3].amount
230
+ assert_equal 0, chain.units[4].amount
231
+ assert_equal 0, chain.units[5].amount
232
+ assert_equal 4, chain.units[6].amount
233
+ assert_equal 0, chain.units[7].amount
234
+ assert_equal 0, chain.units[8].amount
235
+ assert_equal 58, chain.units[9].amount
236
+ assert_equal 0, chain.units[10].amount
237
+ assert_equal 0, chain.units[11].amount
238
+ assert_equal 2, chain.units[12].amount
239
+ end
240
+
241
+ it 'calculates nothing' do
242
+ from = Time.at(DateTime.parse('2013-07-28 00:00:01').to_time, 0.021)
243
+ to = Time.at(DateTime.parse('2013-07-28 00:00:01').to_time, 0.021)
244
+ chain = DurationChain.new(from, to, [Millennium, Century, Decade, Year, Month, Week, Day, Hour, Minute, Second, Millisecond, Microsecond, Nanosecond])
245
+
246
+ assert_equal 0, chain.units[0].amount
247
+ assert_equal 0, chain.units[1].amount
248
+ assert_equal 0, chain.units[2].amount
249
+ assert_equal 0, chain.units[3].amount
250
+ assert_equal 0, chain.units[4].amount
251
+ assert_equal 0, chain.units[5].amount
252
+ assert_equal 0, chain.units[6].amount
253
+ assert_equal 0, chain.units[7].amount
254
+ assert_equal 0, chain.units[8].amount
255
+ assert_equal 0, chain.units[9].amount
256
+ assert_equal 0, chain.units[10].amount
257
+ assert_equal 0, chain.units[11].amount
258
+ assert_equal 0, chain.units[12].amount
259
+ end
260
+
261
+ end
262
+
263
+ end
264
+
265
+ end
266
+
267
+ end