timerizer 0.2.1 → 0.3.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: 0356b2737bb29434b5946aaeefd72a6d031fed12
4
- data.tar.gz: 4ceffb7da4b98e9b149f589dccd04c9486edcd7c
3
+ metadata.gz: 4180c0ffb871e50a47486d122ae17fc42f37cab8
4
+ data.tar.gz: dad648d7c6fb1f996b61d5aa1c55a7c2637abc52
5
5
  SHA512:
6
- metadata.gz: 11e0ee504f1b44ec22a1364ea9395602727b29050cf9dd8386bcdee8491a053ca2e7608e3a033f469d3bd4b59cc8d3a5a14e8bb1436ebe6da4921183f6ed908a
7
- data.tar.gz: 5f45158efea1cdfae177b0460388fd489062bf8e75df7c3ab2ae8c12513a4826d844bf1f5e8469b72fc0528a6e34996f75adf3d85e425553c6641fabe49af712
6
+ metadata.gz: 369ea12d3065905306b0649f81b6517fe49d50cd2ddd601cb7d7132571ea07b21846760bc24e75b3dee56aab841c7b42a6107f54283472e014905910ba1bbca5
7
+ data.tar.gz: 02487b58f59677d6cf481f3a3a78a6fe10f04bb598a67a445e8e1e81cb73395267526913041a53c95477882f3bd7fe95868da9a2c190bf13791775b31b4a1510
data/lib/timerizer.rb CHANGED
@@ -1,621 +1,7 @@
1
- require 'date'
1
+ require "date"
2
+ require_relative "./timerizer/core"
2
3
 
3
- # Represents a relative amount of time. For example, '`5 days`', '`4 years`', and '`5 years, 4 hours, 3 minutes, 2 seconds`' are all RelativeTimes.
4
- class RelativeTime
5
- @@units = {
6
- :second => :seconds,
7
- :minute => :minutes,
8
- :hour => :hours,
9
- :day => :days,
10
- :week => :weeks,
11
- :month => :months,
12
- :year => :years,
13
- :decade => :decades,
14
- :century => :centuries,
15
- :millennium => :millennia
16
- }
17
-
18
- @@in_seconds = {
19
- :second => 1,
20
- :minute => 60,
21
- :hour => 3600,
22
- :day => 86400,
23
- :week => 604800
24
- }
25
-
26
- @@in_months = {
27
- :month => 1,
28
- :year => 12,
29
- :decade => 120,
30
- :century => 1200,
31
- :millennium => 12000
32
- }
33
-
34
- # Average amount of time in a given unit. Used internally within the {#average} and {#unaverage} methods.
35
- @@average_seconds = {
36
- :month => 2629746,
37
- :year => 31556952
38
- }
39
-
40
- # Default syntax formats that can be used with #to_s
41
- # @see #to_s
42
- @@syntaxes = {
43
- :micro => {
44
- :units => {
45
- :seconds => 's',
46
- :minutes => 'm',
47
- :hours => 'h',
48
- :days => 'd',
49
- :weeks => 'w',
50
- :months => 'mn',
51
- :years => 'y',
52
- },
53
- :separator => '',
54
- :delimiter => ' ',
55
- :count => 1
56
- },
57
- :short => {
58
- :units => {
59
- :seconds => 'sec',
60
- :minutes => 'min',
61
- :hours => 'hr',
62
- :days => 'd',
63
- :weeks => 'wk',
64
- :months => 'mn',
65
- :years => 'yr',
66
- :centuries => 'ct',
67
- :millenia => 'ml'
68
- },
69
- :separator => '',
70
- :delimiter => ' ',
71
- :count => 2
72
- },
73
- :long => {
74
- :units => {
75
- :seconds => ['second', 'seconds'],
76
- :minutes => ['minute', 'minutes'],
77
- :hours => ['hour', 'hours'],
78
- :days => ['day', 'days'],
79
- :weeks => ['week', 'weeks'],
80
- :months => ['month', 'months'],
81
- :years => ['year', 'years'],
82
- :centuries => ['century', 'centuries'],
83
- :millennia => ['millenium', 'millenia'],
84
- }
85
- }
86
- }
87
-
88
- # All potential units. Key is the unit name, and the value is its plural form.
89
- def self.units
90
- @@units
91
- end
92
-
93
- # Unit values in seconds. If a unit is not present in this hash, it is assumed to be in the {@@in_months} hash.
94
- def self.units_in_seconds
95
- @@in_seconds
96
- end
97
-
98
- # Unit values in months. If a unit is not present in this hash, it is assumed to be in the {@@in_seconds} hash.
99
- def self.units_in_months
100
- @@in_months
101
- end
102
-
103
- # Initialize a new instance of RelativeTime.
104
- # @overload new(hash)
105
- # @param [Hash] units The base units to initialize with
106
- # @option units [Integer] :seconds The number of seconds
107
- # @option units [Integer] :months The number of months
108
- # @overload new(count, unit)
109
- # @param [Integer] count The number of units to initialize with
110
- # @param [Symbol] unit The unit to initialize. See {RelativeTime#units}
111
- def initialize(count = 0, unit = :second)
112
- if count.is_a? Hash
113
- units = count
114
- units.default = 0
115
- @seconds, @months = units.values_at(:seconds, :months)
116
- else
117
- @seconds = @months = 0
118
-
119
- if @@in_seconds.has_key?(unit)
120
- @seconds = count * @@in_seconds.fetch(unit)
121
- elsif @@in_months.has_key?(unit)
122
- @months = count * @@in_months.fetch(unit)
123
- end
124
- end
125
- end
126
-
127
- # Compares two RelativeTimes to determine if they are equal
128
- # @param [RelativeTime] time The RelativeTime to compare
129
- # @return [Boolean] True if both RelativeTimes are equal
130
- # @note Be weary of rounding; this method compares both RelativeTimes' base units
131
- def ==(time)
132
- if time.is_a?(RelativeTime)
133
- @seconds == time.get(:seconds) && @months == time.get(:months)
134
- else
135
- false
136
- end
137
- end
138
-
139
- # Return the number of base units in a RelativeTime.
140
- # @param [Symbol] unit The unit to return, either :seconds or :months
141
- # @return [Integer] The requested unit count
142
- # @raise [ArgumentError] Unit requested was not :seconds or :months
143
- def get(unit)
144
- if unit == :seconds
145
- @seconds
146
- elsif unit == :months
147
- @months
148
- else
149
- raise ArgumentError
150
- end
151
- end
152
-
153
- # Determines the time between RelativeTime and the given time.
154
- # @param [Time] time The initial time.
155
- # @return [Time] The difference between the current RelativeTime and the given time
156
- # @example 5 hours before January 1st, 2000 at noon
157
- # 5.minutes.before(Time.new(2000, 1, 1, 12, 00, 00))
158
- # => 2000-01-01 11:55:00 -0800
159
- # @see #ago
160
- # @see #after
161
- # @see #from_now
162
- def before(time)
163
- time = time.to_time - @seconds
164
-
165
- new_month = time.month - self.months
166
- new_year = time.year - self.years
167
- while new_month < 1
168
- new_month += 12
169
- new_year -= 1
170
- end
171
- if Date.valid_date?(new_year, new_month, time.day)
172
- new_day = time.day
173
- else
174
- new_day = Date.new(new_year, new_month).days_in_month
175
- end
176
-
177
- new_time = Time.new(
178
- new_year, new_month, new_day,
179
- time.hour, time.min, time.sec
180
- )
181
- Time.at(new_time.to_i, time.nsec/1000)
182
- end
183
-
184
- # Return the time between the RelativeTime and the current time.
185
- # @return [Time] The difference between the current RelativeTime and Time#now
186
- # @see #before
187
- def ago
188
- self.before(Time.now)
189
- end
190
-
191
- # Return the time after the given time according to the current RelativeTime.
192
- # @param [Time] time The starting time
193
- # @return [Time] The time after the current RelativeTime and the given time
194
- # @see #before
195
- def after(time)
196
- time = time.to_time + @seconds
197
-
198
- new_year = time.year + self.years
199
- new_month = time.month + self.months
200
- while new_month > 12
201
- new_year += 1
202
- new_month -= 12
203
- end
204
- if Date.valid_date?(new_year, new_month, time.day)
205
- new_day = time.day
206
- else
207
- new_day = Date.new(new_year, new_month).days_in_month
208
- end
209
-
210
-
211
- new_time = Time.new(
212
- new_year, new_month, new_day,
213
- time.hour, time.min, time.sec
214
- )
215
- Time.at(new_time.to_i, time.nsec/1000.0)
216
- end
217
-
218
- # Return the time after the current time and the RelativeTime.
219
- # @return [Time] The time after the current time
220
- def from_now
221
- self.after(Time.now)
222
- end
223
-
224
- @@units.each do |unit, plural|
225
- in_method = "in_#{plural}"
226
- count_method = plural
227
- superior_unit = @@units.keys.index(unit) + 1
228
-
229
- if @@in_seconds.has_key? unit
230
- class_eval "
231
- def #{in_method}
232
- @seconds / #{@@in_seconds[unit]}
233
- end
234
- "
235
- elsif @@in_months.has_key? unit
236
- class_eval "
237
- def #{in_method}
238
- @months / #{@@in_months[unit]}
239
- end
240
- "
241
- end
242
-
243
- in_superior = "in_#{@@units.values[superior_unit]}"
244
- count_superior = @@units.keys[superior_unit]
245
-
246
-
247
- class_eval "
248
- def #{count_method}
249
- time = self.#{in_method}
250
- if @@units.length > #{superior_unit}
251
- time -= self.#{in_superior}.#{count_superior}.#{in_method}
252
- end
253
- time
254
- end
255
- "
256
- end
257
-
258
- # Average second-based units to month-based units.
259
- # @return [RelativeTime] The averaged RelativeTime
260
- # @example
261
- # 5.weeks.average
262
- # => 1 month, 4 days, 13 hours, 30 minutes, 54 seconds
263
- # @see #average!
264
- # @see #unaverage
265
- def average
266
- if @seconds > 0
267
- months = (@seconds / @@average_seconds[:month])
268
- seconds = @seconds - months.months.unaverage.get(:seconds)
269
- RelativeTime.new(
270
- :seconds => seconds,
271
- :months => months + @months
272
- )
273
- else
274
- self
275
- end
276
- end
277
-
278
- # Destructively average second-based units to month-based units.
279
- # @see #average
280
- def average!
281
- averaged = self.average
282
- @seconds = averaged.get(:seconds)
283
- @months = averaged.get(:months)
284
- self
285
- end
286
-
287
- # Average month-based units to second-based units.
288
- # @return [RelativeTime] the unaveraged RelativeTime.
289
- # @example
290
- # 1.month.unaverage
291
- # => 4 weeks, 2 days, 10 hours, 29 minutes, 6 seconds
292
- # @see #average
293
- # @see #unaverage!
294
- def unaverage
295
- seconds = @@average_seconds[:month] * @months
296
- seconds += @seconds
297
- RelativeTime.new(:seconds => seconds)
298
- end
299
-
300
- # Destructively average month-based units to second-based units.
301
- # @see #unaverage
302
- def unaverage!
303
- unaveraged = self.average
304
- @seconds = unaverage.get(:seconds)
305
- @months = unaverage.get(:months)
306
- self
307
- end
308
-
309
- # Add two {RelativeTime}s together.
310
- # @raise ArgumentError Argument isn't a {RelativeTime}
311
- # @see #-
312
- def +(time)
313
- raise ArgumentError unless time.is_a?(RelativeTime)
314
- RelativeTime.new({
315
- :seconds => @seconds + time.get(:seconds),
316
- :months => @months + time.get(:months)
317
- })
318
- end
319
-
320
- # Find the difference between two {RelativeTime}s.
321
- # @raise ArgumentError Argument isn't a {RelativeTime}
322
- # @see #+
323
- def -(time)
324
- raise ArgumentError unless time.is_a?(RelativeTime)
325
- RelativeTime.new({
326
- :seconds => @seconds - time.get(:seconds),
327
- :months => @months - time.get(:months)
328
- })
329
- end
330
-
331
- # Converts {RelativeTime} to {WallClock}
332
- # @return [WallClock] {RelativeTime} as {WallClock}
333
- # @example
334
- # (17.hours 30.minutes).to_wall
335
- # # => 5:30:00 PM
336
- def to_wall
337
- raise WallClock::TimeOutOfBoundsError if @months > 0
338
- WallClock.new(:second => @seconds)
339
- end
340
-
341
- # Convert {RelativeTime} to a human-readable format.
342
- # @overload to_s(syntax)
343
- # @param [Symbol] syntax The syntax from @@syntaxes to use
344
- # @overload to_s(hash)
345
- # @param [Hash] hash The custom hash to use
346
- # @option hash [Hash] :units The unit names to use. See @@syntaxes for examples
347
- # @option hash [Integer] :count The maximum number of units to output. `1` would output only the unit of greatest example (such as the hour value in `1.hour 3.minutes 2.seconds`).
348
- # @option hash [String] :separator The separator to use in between a unit and its value
349
- # @option hash [String] :delimiter The delimiter to use in between different unit-value pairs
350
- # @example
351
- # (14.months 49.hours).to_s
352
- # => 2 years, 2 months, 3 days, 1 hour
353
- # (1.day 3.hours 4.minutes).to_s(:short)
354
- # => 1d 3hr
355
- # @raise KeyError Symbol argument isn't in @@syntaxes
356
- # @raise ArgumentError Argument isn't a hash (if not a symbol)
357
- # @see @@syntaxes
358
- def to_s(syntax = :long)
359
- if syntax.is_a? Symbol
360
- syntax = @@syntaxes.fetch(syntax)
361
- end
362
-
363
- raise ArgumentError unless syntax.is_a? Hash
364
- times = []
365
-
366
- if syntax[:count].nil? || syntax[:count] == :all
367
- syntax[:count] = @@units.count
368
- end
369
- units = syntax.fetch(:units)
370
-
371
- count = 0
372
- units = Hash[units.to_a.reverse]
373
- units.each do |unit, (singular, plural)|
374
- if count < syntax.fetch(:count)
375
- time = self.respond_to?(unit) ? self.send(unit) : 0
376
-
377
- if time > 1 && !plural.nil?
378
- times << [time, plural]
379
- count += 1
380
- elsif time > 0
381
- times << [time, singular]
382
- count += 1
383
- end
384
- end
385
- end
386
-
387
- times.map do |time|
388
- time.join(syntax[:separator] || ' ')
389
- end.join(syntax[:delimiter] || ', ')
390
- end
391
- end
392
-
393
- # Represents a time, but not a date. '`7:00 PM`' would be an example of a WallClock object
394
- class WallClock
395
- # Represents an error where an invalid meridiem was passed to WallClock.
396
- # @see #new
397
- class InvalidMeridiemError < ArgumentError; end
398
- # Represents an error where a time beyond 24 hours was passed to WallClock.
399
- # @see #new
400
- class TimeOutOfBoundsError < ArgumentError; end
401
-
402
- # Initialize a new instance of WallClock
403
- # @overload new(hash)
404
- # @param [Hash] units The units to initialize with
405
- # @option units [Integer] :hour The hour to initialize with
406
- # @option units [Integer] :minute The minute to initialize with
407
- # @option units [Integer] :second The second to initialize with
408
- # @overload new(hour, minute, meridiem)
409
- # @param [Integer] hour The hour to initialize with
410
- # @param [Integer] minute The minute to initialize with
411
- # @param [Symbol] meridiem The meridiem to initialize with (`:am` or `:pm`)
412
- # @overload new(hour, minute, second, meridiem)
413
- # @param [Integer] hour The hour to initialize with
414
- # @param [Integer] minute The minute to initialize with
415
- # @param [Integer] second The second to initialize with
416
- # @param [Symbol] meridiem The meridiem to initialize with (`:am` or `:pm`)
417
- # @overload new(seconds)
418
- # @param [Integer] seconds The number of seconds to initialize with (for use with #to_i)
419
- # @raise InvalidMeridiemError Meridiem is not `:am` or `:pm`
420
- def initialize(hour = nil, minute = nil, second = 0, meridiem = :am)
421
- units = nil
422
- if hour.is_a?(Integer) && minute.nil?
423
- units = {:second => hour}
424
- elsif hour.is_a?(Hash)
425
- units = hour
426
- end
427
-
428
- if !units.nil?
429
- second = units[:second] || 0
430
- minute = units[:minute] || 0
431
- hour = units[:hour] || 0
432
- else
433
- if second.is_a?(String) || second.is_a?(Symbol)
434
- meridiem = second
435
- second = 0
436
- end
437
-
438
- meridiem = meridiem.downcase.to_sym
439
- if !(meridiem == :am || meridiem == :pm)
440
- raise InvalidMeridiemError
441
- elsif meridiem == :pm && hour > 12
442
- raise TimeOutOfBoundsError, "hour must be <= 12 for PM"
443
- elsif hour >= 24 || minute >= 60 || second >= 60
444
- raise TimeOutOfBoundsError
445
- end
446
-
447
- hour += 12 if (meridiem == :pm and !(hour == 12))
448
- end
449
-
450
- @seconds =
451
- RelativeTime.units_in_seconds.fetch(:hour) * hour +
452
- RelativeTime.units_in_seconds.fetch(:minute) * minute +
453
- second
454
-
455
- if @seconds >= RelativeTime.units_in_seconds.fetch(:day)
456
- raise TimeOutOfBoundsError
457
- end
458
- end
459
-
460
- # Takes a string and turns it into a WallClock time
461
- # @param [String] string The string to convert
462
- # @return [WallClock] The time as a WallClock
463
- # @example
464
- # WallClock.from_string("10:30 PM")
465
- # # => 10:30:00 PM
466
- # WallClock.from_string("13:01:23")
467
- # # => 1:01:23 PM
468
- # @see #to_s
469
- def self.from_string(string)
470
- time, meridiem = string.split(' ', 2)
471
- hour, minute, second = time.split(':', 3)
472
- WallClock.new(hour.to_i, minute.to_i, second.to_i || 0, meridiem || :am)
473
- end
474
-
475
- # Returns the time of the WallClock on a date
476
- # @param [Date] date The date to apply the time on
477
- # @return [Time] The time after the given date
478
- # @example yesterday at 5:00
479
- # time = WallClock.new(5, 00, :pm)
480
- # time.on(Date.yesterday)
481
- # => 2000-1-1 17:00:00 -0800
482
- def on(date)
483
- date.to_date.to_time + @seconds
484
- end
485
-
486
- # Comparse two {WallClock}s.
487
- # @return [Boolean] True if the WallClocks are identical
488
- def ==(time)
489
- if time.is_a? WallClock
490
- self.in_seconds == time.in_seconds
491
- else
492
- false
493
- end
494
- end
495
-
496
- # Get the time of the WallClock, in seconds
497
- # @return [Integer] The total time of the WallClock, in seconds
498
- def in_seconds
499
- @seconds
500
- end
501
-
502
- # Get the time of the WallClock, in minutes
503
- # @return [Integer] The total time of the WallClock, in minutes
504
- def in_minutes
505
- @seconds / RelativeTime.units_in_seconds[:minute]
506
- end
507
-
508
- # Get the time of the WallClock, in hours
509
- # @return [Integer] The total time of the WallClock, in hours
510
- def in_hours
511
- @seconds / RelativeTime.units_in_seconds[:hour]
512
- end
513
-
514
- # Get the second of the WallClock.
515
- # @return [Integer] The second component of the WallClock
516
- def second
517
- self.to_relative.seconds
518
- end
519
-
520
- # Get the minute of the WallClock.
521
- # @return [Integer] The minute component of the WallClock
522
- def minute
523
- self.to_relative.minutes
524
- end
525
-
526
- # Get the hour of the WallClock.
527
- # @param [Symbol] system The houring system to use (either `:twelve_hour` or `:twenty_four_hour`; default `:twenty_four_hour`)
528
- # @return [Integer] The hour component of the WallClock
529
- def hour(system = :twenty_four_hour)
530
- hour = self.to_relative.hours
531
- if system == :twelve_hour
532
- if hour == 0
533
- 12
534
- elsif hour > 12
535
- hour - 12
536
- else
537
- hour
538
- end
539
- elsif (system == :twenty_four_hour)
540
- hour
541
- else
542
- raise ArgumentError, "system should be :twelve_hour or :twenty_four_hour"
543
- end
544
- end
545
-
546
- # Get the meridiem of the WallClock.
547
- # @return [Symbol] The meridiem (either `:am` or `:pm`)
548
- def meridiem
549
- if self.hour > 12 || self.hour == 0
550
- :pm
551
- else
552
- :am
553
- end
554
- end
555
-
556
- # Converts self to {WallClock}
557
- # @see Time#to_wall
558
- def to_wall
559
- self
560
- end
561
-
562
- # Converts {WallClock} to {RelativeTime}
563
- # @return [RelativeTime] {WallClock} as {RelativeTime}
564
- # @example
565
- # time = WallClock.new(5, 30, :pm)
566
- # time.to_relative
567
- # => 5 hours, 30 minutes
568
- def to_relative
569
- @seconds.seconds
570
- end
571
-
572
- # Get the time of the WallClock in a more portable format (for a database, for example)
573
- # @see #in_seconds
574
- def to_i
575
- self.in_seconds
576
- end
577
-
578
- # Convert {WallClock} to a human-readable format.
579
- # @param [Symbol] system The hour system to use (`:twelve_hour` or `:twenty_four_hour`; default `:twelve_hour`)
580
- # @param [Hash] options Extra options for the string to use
581
- # @option options [Boolean] :use_seconds Whether or not to include seconds in the conversion to a string
582
- # @option options [Boolean] :include_meridian Whether or not to include the meridian for a twelve-hour time
583
- # @example
584
- # time = WallClock.new(5, 37, 41, :pm)
585
- # time.to_s
586
- # => "5:37:41 PM"
587
- # time.to_s(:twenty_four_hour, :use_seconds => true)
588
- # => "17:37:41"
589
- # time.to_s(:twelve_hour, :use_seconds => false, :include_meridiem => false)
590
- # => "5:37"
591
- # time.to_s(:twenty_four_hour, :use_seconds =>false)
592
- # => "17:37"
593
- # @raise ArgumentError Argument isn't a proper system
594
- def to_s(system = :twelve_hour, options = {})
595
- options = {:use_seconds => true, :include_meridiem => true}.merge(options)
596
- pad = "%02d"
597
- meridiem = self.meridiem.to_s.upcase
598
- hour = self.hour(system)
599
- minute = pad % self.minute
600
- second = pad % self.second
601
-
602
- string = [hour, minute].join(':')
603
- if options[:use_seconds]
604
- string = [string, second].join(':')
605
- end
606
-
607
- case system
608
- when :twelve_hour
609
- options[:include_meridiem] ? [string, meridiem].join(' ') : string
610
- when :twenty_four_hour
611
- string
612
- else
613
- raise ArgumentError, "system should be :twelve_hour or :twenty_four_hour"
614
- end
615
- end
616
- end
617
-
618
- # {Time} class monkeywrenched with {RelativeTime} support.
4
+ # {Time} class monkey-patched with {Timerizer::Duration} support.
619
5
  class Time
620
6
  # Represents an error where two times were expected to be in the future, but were in the past.
621
7
  # @see #until
@@ -650,7 +36,7 @@ class Time
650
36
 
651
37
  alias_method :add, :+
652
38
  def +(time)
653
- if time.is_a? RelativeTime
39
+ if time.is_a?(Timerizer::Duration)
654
40
  time.after(self)
655
41
  else
656
42
  self.add(time)
@@ -659,7 +45,7 @@ class Time
659
45
 
660
46
  alias_method :subtract, :-
661
47
  def -(time)
662
- if time.is_a? RelativeTime
48
+ if time.is_a?(Timerizer::Duration)
663
49
  time.before(self)
664
50
  else
665
51
  self.subtract(time)
@@ -668,7 +54,7 @@ class Time
668
54
 
669
55
  # Calculates the time until a given time
670
56
  # @param [Time] time The time until now to calculate
671
- # @return [RelativeTime] The time until the provided time
57
+ # @return [Duration] The time until the provided time
672
58
  # @raise[TimeIsInThePastException] The provided time is in the past
673
59
  # @example
674
60
  # Time.until(Time.new(2012, 12, 25))
@@ -683,7 +69,7 @@ class Time
683
69
 
684
70
  # Calculates the time since a given time
685
71
  # @param [Time] time The time to calculate since now
686
- # @return [RelativeTime] The time since the provided time
72
+ # @return [Duration] The time since the provided time
687
73
  # @raise[TimeIsInTheFutureException] The provided time is in the future
688
74
  # @example
689
75
  # Time.since(Time.new(2011, 10, 31))
@@ -699,7 +85,7 @@ class Time
699
85
  # Calculate the amount of time between two times.
700
86
  # @param [Time] time1 The initial time
701
87
  # @param [Time] time2 The final time
702
- # @return [RelativeTime] Calculated time between time1 and time2
88
+ # @return [Duration] Calculated time between time1 and time2
703
89
  # @example
704
90
  # Time.between(1.minute.ago, 1.hour.ago)
705
91
  # => 59.minutes
@@ -709,7 +95,7 @@ class Time
709
95
  def self.between(time1, time2)
710
96
  time_between = (time2.to_time - time1.to_time).abs
711
97
 
712
- RelativeTime.new(time_between.round)
98
+ Timerizer::Duration.new(seconds: time_between.round)
713
99
  end
714
100
 
715
101
  # Convert {Time} to {Date}.
@@ -727,19 +113,19 @@ class Time
727
113
  self
728
114
  end
729
115
 
730
- # Converts {Time} to {WallClock}
731
- # @return [WallClock] {Time} as {WallClock}
116
+ # Converts {Time} to {Timerizer::WallClock}
117
+ # @return [Timerizer::WallClock] {Time} as {Timerizer::WallClock}
732
118
  # @example
733
119
  # time = Time.now.to_wall
734
120
  # Date.tomorrow.at(time)
735
121
  # => 2000-1-2 13:13:27 -0800
736
122
  # # "Same time tomorrow?"
737
123
  def to_wall
738
- WallClock.new(self.hour, self.min, self.sec)
124
+ Timerizer::WallClock.new(self.hour, self.min, self.sec)
739
125
  end
740
126
  end
741
127
 
742
- # {Date} class monkeywrenched with {RelativeTime} helpers.
128
+ # {Date} class monkey-patched with {Timerizer::Duration} helpers.
743
129
  class Date
744
130
  # Return the number of days in a given month.
745
131
  # @return [Integer] Number of days in the month of the {Date}.
@@ -783,19 +169,66 @@ class Date
783
169
  end
784
170
  end
785
171
 
786
- # Monkeywrenched {Integer} class enabled to return {RelativeTime} objects.
172
+ # Monkey-patched {Integer} class enabled to return {Timerizer::Duration}s.
787
173
  # @example
788
174
  # 5.minutes
789
- # => 5 minutes
790
- # @see {RelativeTime#units}
175
+ # # => 5 minutes
176
+ # @see Timerizer::Duration::UNITS
791
177
  class Integer
792
- RelativeTime.units.each do |unit, plural|
793
- class_eval "
794
- def #{unit}(added_time = RelativeTime.new)
795
- time = RelativeTime.new(self, :#{unit})
796
- time + added_time unless added_time.nil?
178
+ private
179
+
180
+ # @!macro [attach] _define_duration_unit
181
+ # @method $1(other = nil)
182
+ #
183
+ # Return a {Timerizer::Duration} with `self` of the given unit. This
184
+ # method is a helper that is equivalent to
185
+ # `Timerizer::Duration::new($1: self)`.
186
+ #
187
+ # @param [Timerizer::Duration, nil] other Another duration to add to the
188
+ # resulting duration, if present. This argument allows "chaining" multiple
189
+ # durations together, to combine multiple units succiently.
190
+ #
191
+ # @return [Timerizer::Duration] the quantity of the unit in the duration.
192
+ #
193
+ # @see Timerizer::Duration#initialize
194
+ #
195
+ # @example
196
+ # n.$1 == Timerizer::Duration.new($1: n)
197
+ # 5.minutes == Timerizer::Duration.new(minutes: 5)
198
+ # (1.week 1.day) == 8.days # "Chaining" multiple units
199
+ # (n.$1 x.minutes) == (n.$1 + x.minutes)
200
+ def self._define_duration_unit(unit)
201
+ define_method(unit) do |other = nil|
202
+ duration = Timerizer::Duration.new(unit => self)
203
+
204
+ if other.nil?
205
+ duration
206
+ else
207
+ duration + other
797
208
  end
798
- "
799
- alias_method(plural, unit)
209
+ end
800
210
  end
211
+
212
+ public
213
+
214
+ self._define_duration_unit(:seconds)
215
+ self._define_duration_unit(:minutes)
216
+ self._define_duration_unit(:hours)
217
+ self._define_duration_unit(:days)
218
+ self._define_duration_unit(:weeks)
219
+ self._define_duration_unit(:months)
220
+ self._define_duration_unit(:years)
221
+ self._define_duration_unit(:decades)
222
+ self._define_duration_unit(:centuries)
223
+ self._define_duration_unit(:millennia)
224
+ self._define_duration_unit(:second)
225
+ self._define_duration_unit(:minute)
226
+ self._define_duration_unit(:hour)
227
+ self._define_duration_unit(:day)
228
+ self._define_duration_unit(:week)
229
+ self._define_duration_unit(:month)
230
+ self._define_duration_unit(:year)
231
+ self._define_duration_unit(:decade)
232
+ self._define_duration_unit(:century)
233
+ self._define_duration_unit(:millennium)
801
234
  end