timerizer 0.0.3 → 0.1.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.
- data/lib/timerizer.rb +360 -54
- metadata +1 -1
data/lib/timerizer.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'date'
|
2
2
|
|
3
|
-
# Represents a relative amount of time. For example, `5 days
|
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
4
|
class RelativeTime
|
5
|
-
# All potential units. Key is the unit name, and the value is its plural form.
|
6
5
|
@@units = {
|
7
6
|
:second => :seconds,
|
8
7
|
:minute => :minutes,
|
@@ -16,7 +15,6 @@ class RelativeTime
|
|
16
15
|
:millennium => :millennia
|
17
16
|
}
|
18
17
|
|
19
|
-
# Unit values in seconds. If a unit is not present in this hash, it is assumed to be in the {@@in_months} hash.
|
20
18
|
@@in_seconds = {
|
21
19
|
:second => 1,
|
22
20
|
:minute => 60,
|
@@ -25,7 +23,6 @@ class RelativeTime
|
|
25
23
|
:week => 604800
|
26
24
|
}
|
27
25
|
|
28
|
-
# Unit values in months. If a unit is not present in this hash, it is assumed to be in the {@@in_seconds} hash.
|
29
26
|
@@in_months = {
|
30
27
|
:month => 1,
|
31
28
|
:year => 12,
|
@@ -40,6 +37,69 @@ class RelativeTime
|
|
40
37
|
:year => 31556952
|
41
38
|
}
|
42
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
|
+
|
43
103
|
# Initialize a new instance of RelativeTime.
|
44
104
|
# @overload new(hash)
|
45
105
|
# @param [Hash] units The base units to initialize with
|
@@ -47,21 +107,20 @@ class RelativeTime
|
|
47
107
|
# @option units [Fixnum] :months The number of months
|
48
108
|
# @overload new(count, unit)
|
49
109
|
# @param [Fixnum] count The number of units to initialize with
|
50
|
-
# @param [Symbol] unit The unit to initialize. See {
|
110
|
+
# @param [Symbol] unit The unit to initialize. See {RelativeTime#units}
|
51
111
|
def initialize(count = 0, unit = :second)
|
52
|
-
if
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
@seconds = 0
|
59
|
-
@months = 0
|
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
|
60
118
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
65
124
|
end
|
66
125
|
end
|
67
126
|
|
@@ -70,8 +129,11 @@ class RelativeTime
|
|
70
129
|
# @return [Boolean] True if both RelativeTimes are equal
|
71
130
|
# @note Be weary of rounding; this method compares both RelativeTimes' base units
|
72
131
|
def ==(time)
|
73
|
-
|
74
|
-
|
132
|
+
if time.is_a?(RelativeTime)
|
133
|
+
@seconds == time.get(:seconds) && @months == time.get(:months)
|
134
|
+
else
|
135
|
+
false
|
136
|
+
end
|
75
137
|
end
|
76
138
|
|
77
139
|
# Return the number of base units in a RelativeTime.
|
@@ -79,16 +141,20 @@ class RelativeTime
|
|
79
141
|
# @return [Fixnum] The requested unit count
|
80
142
|
# @raise [ArgumentError] Unit requested was not :seconds or :months
|
81
143
|
def get(unit)
|
82
|
-
|
83
|
-
|
84
|
-
|
144
|
+
if unit == :seconds
|
145
|
+
@seconds
|
146
|
+
elsif unit == :months
|
147
|
+
@months
|
148
|
+
else
|
149
|
+
raise ArgumentError
|
150
|
+
end
|
85
151
|
end
|
86
152
|
|
87
153
|
# Determines the time between RelativeTime and the given time.
|
88
154
|
# @param [Time] time The initial time.
|
89
155
|
# @return [Time] The difference between the current RelativeTime and the given time
|
90
156
|
# @example 5 hours before January 1st, 2000 at noon
|
91
|
-
# 5.minutes.before(Time.
|
157
|
+
# 5.minutes.before(Time.new(2000, 1, 1, 12, 00, 00))
|
92
158
|
# => 2000-01-01 11:55:00 -0800
|
93
159
|
# @see #ago
|
94
160
|
# @see #after
|
@@ -102,7 +168,7 @@ class RelativeTime
|
|
102
168
|
new_month += 12
|
103
169
|
new_year -= 1
|
104
170
|
end
|
105
|
-
if
|
171
|
+
if Date.valid_date?(new_year, new_month, time.day)
|
106
172
|
new_day = time.day
|
107
173
|
else
|
108
174
|
new_day = Date.new(new_year, new_month).days_in_month
|
@@ -135,7 +201,7 @@ class RelativeTime
|
|
135
201
|
new_year += 1
|
136
202
|
new_month -= 12
|
137
203
|
end
|
138
|
-
if
|
204
|
+
if Date.valid_date?(new_year, new_month, time.day)
|
139
205
|
new_day = time.day
|
140
206
|
else
|
141
207
|
new_day = Date.new(new_year, new_month).days_in_month
|
@@ -161,9 +227,9 @@ class RelativeTime
|
|
161
227
|
superior_unit = @@units.keys.index(unit) + 1
|
162
228
|
|
163
229
|
define_method(in_method) do
|
164
|
-
if
|
230
|
+
if @@in_seconds.has_key?(unit)
|
165
231
|
@seconds / @@in_seconds[unit]
|
166
|
-
elsif
|
232
|
+
elsif @@in_months.has_key?(unit)
|
167
233
|
@months / @@in_months[unit]
|
168
234
|
end
|
169
235
|
end
|
@@ -173,7 +239,7 @@ class RelativeTime
|
|
173
239
|
count_superior = @@units.keys[superior_unit]
|
174
240
|
|
175
241
|
time = self.send(in_method)
|
176
|
-
if
|
242
|
+
if @@units.length > superior_unit
|
177
243
|
time -= self.send(in_superior).send(count_superior).send(in_method)
|
178
244
|
end
|
179
245
|
time
|
@@ -188,14 +254,16 @@ class RelativeTime
|
|
188
254
|
# @see #average!
|
189
255
|
# @see #unaverage
|
190
256
|
def average
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
257
|
+
if @seconds > 0
|
258
|
+
months = (@seconds / @@average_seconds[:month])
|
259
|
+
seconds = @seconds - months.months.unaverage.get(:seconds)
|
260
|
+
RelativeTime.new(
|
261
|
+
:seconds => seconds,
|
262
|
+
:months => months + @months
|
263
|
+
)
|
264
|
+
else
|
265
|
+
self
|
266
|
+
end
|
199
267
|
end
|
200
268
|
|
201
269
|
# Destructively average second-based units to month-based units.
|
@@ -217,7 +285,7 @@ class RelativeTime
|
|
217
285
|
def unaverage
|
218
286
|
seconds = @@average_seconds[:month] * @months
|
219
287
|
seconds += @seconds
|
220
|
-
RelativeTime.new(
|
288
|
+
RelativeTime.new(:seconds => seconds)
|
221
289
|
end
|
222
290
|
|
223
291
|
# Destructively average month-based units to second-based units.
|
@@ -251,32 +319,252 @@ class RelativeTime
|
|
251
319
|
})
|
252
320
|
end
|
253
321
|
|
322
|
+
# Converts {RelativeTime} to {WallClock}
|
323
|
+
# @return [WallClock] {RelativeTime} as {WallClock}
|
324
|
+
# @example
|
325
|
+
# (17.hours 30.minutes).to_wall
|
326
|
+
# # => 5:30:00 PM
|
327
|
+
def to_wall
|
328
|
+
raise WallClock::TimeOutOfBoundsError if @months > 0
|
329
|
+
WallClock.new(:second => @seconds)
|
330
|
+
end
|
331
|
+
|
254
332
|
# Convert {RelativeTime} to a human-readable format.
|
333
|
+
# @overload to_s(syntax)
|
334
|
+
# @param [Symbol] syntax The syntax from @@syntaxes to use
|
335
|
+
# @overload to_s(hash)
|
336
|
+
# @param [Hash] hash The custom hash to use
|
337
|
+
# @option hash [Hash] :units The unit names to use. See @@syntaxes for examples
|
338
|
+
# @option hash [Fixnum] :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`).
|
339
|
+
# @option hash [String] :separator The separator to use in between a unit and its value
|
340
|
+
# @option hash [String] :delimiter The delimiter to use in between different unit-value pairs
|
255
341
|
# @example
|
256
342
|
# (14.months 49.hours).to_s
|
257
343
|
# => 2 years, 2 months, 3 days, 1 hour
|
258
|
-
|
259
|
-
|
344
|
+
# (1.day 3.hours 4.minutes).to_s(:short)
|
345
|
+
# => 1d 3hr
|
346
|
+
# @raise KeyError Symbol argument isn't in @@syntaxes
|
347
|
+
# @raise ArgumentError Argument isn't a hash (if not a symbol)
|
348
|
+
# @see @@syntaxes
|
349
|
+
def to_s(syntax = :long)
|
350
|
+
if syntax.is_a? Symbol
|
351
|
+
syntax = @@syntaxes.fetch(syntax)
|
352
|
+
end
|
260
353
|
|
261
|
-
|
262
|
-
|
263
|
-
|
354
|
+
raise ArgumentError unless syntax.is_a? Hash
|
355
|
+
times = []
|
356
|
+
|
357
|
+
if syntax[:count].nil? || syntax[:count] == :all
|
358
|
+
syntax[:count] = @@units.count
|
359
|
+
end
|
360
|
+
units = syntax.fetch(:units)
|
361
|
+
|
362
|
+
count = 0
|
363
|
+
units = Hash[units.to_a.reverse]
|
364
|
+
units.each do |unit, (singular, plural)|
|
365
|
+
if count < syntax.fetch(:count)
|
366
|
+
time = self.respond_to?(unit) ? self.send(unit) : 0
|
367
|
+
|
368
|
+
if time > 1 && !plural.nil?
|
369
|
+
times << [time, plural]
|
370
|
+
count += 1
|
371
|
+
elsif time > 0
|
372
|
+
times << [time, singular]
|
373
|
+
count += 1
|
374
|
+
end
|
375
|
+
end
|
264
376
|
end
|
265
377
|
|
266
378
|
times.map do |time|
|
267
|
-
time.join(' ')
|
268
|
-
end.
|
379
|
+
time.join(syntax[:separator] || ' ')
|
380
|
+
end.join(syntax[:delimiter] || ', ')
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
# Represents a time, but not a date. '`7:00 PM`' would be an example of a WallClock object
|
385
|
+
class WallClock
|
386
|
+
# Represents an error where an invalid meridiem was passed to WallClock.
|
387
|
+
# @see #new
|
388
|
+
class InvalidMeridiemError < ArgumentError; end
|
389
|
+
# Represents an error where a time beyond 24 hours was passed to WallClock.
|
390
|
+
# @see #new
|
391
|
+
class TimeOutOfBoundsError < ArgumentError; end
|
392
|
+
|
393
|
+
# Initialize a new instance of WallClock
|
394
|
+
# @overload new(hash)
|
395
|
+
# @param [Hash] units The units to initialize with
|
396
|
+
# @option units [Fixnum] :hour The hour to initialize with
|
397
|
+
# @option units [Fixnum] :minute The minute to initialize with
|
398
|
+
# @option units [Fixnum] :second The second to initialize with
|
399
|
+
# @overload new(hour, minute, meridiem)
|
400
|
+
# @param [Fixnum] hour The hour to initialize with
|
401
|
+
# @param [Fixnum] minute The minute to initialize with
|
402
|
+
# @param [Symbol] meridiem The meridiem to initialize with (`:am` or `:pm`)
|
403
|
+
# @overload new(hour, minute, second, meridiem)
|
404
|
+
# @param [Fixnum] hour The hour to initialize with
|
405
|
+
# @param [Fixnum] minute The minute to initialize with
|
406
|
+
# @param [Fixnum] second The second to initialize with
|
407
|
+
# @param [Symbol] meridiem The meridiem to initialize with (`:am` or `:pm`)
|
408
|
+
# @raise InvalidMeridiemError Meridiem is not `:am` or `:pm`
|
409
|
+
def initialize(hour = 0, minute = 0, second = 0, meridiem = :am)
|
410
|
+
if hour.is_a?(Hash)
|
411
|
+
units = hour
|
412
|
+
|
413
|
+
second = units[:second] || 0
|
414
|
+
minute = units[:minute] || 0
|
415
|
+
hour = units[:hour] || 0
|
416
|
+
else
|
417
|
+
if second.is_a?(String) || second.is_a?(Symbol)
|
418
|
+
meridiem = second
|
419
|
+
second = 0
|
420
|
+
end
|
421
|
+
|
422
|
+
meridiem = meridiem.downcase.to_sym
|
423
|
+
if !(meridiem == :am || meridiem == :pm)
|
424
|
+
raise InvalidMeridiemError
|
425
|
+
elsif meridiem == :pm && hour > 12
|
426
|
+
raise TimeOutOfBoundsError, "hour must be <= 12 for PM"
|
427
|
+
elsif hour >= 24 || minute >= 60 || second >= 60
|
428
|
+
raise TimeOutOfBoundsError
|
429
|
+
end
|
430
|
+
|
431
|
+
hour += 12 if meridiem == :pm
|
432
|
+
end
|
433
|
+
|
434
|
+
@seconds =
|
435
|
+
RelativeTime.units_in_seconds.fetch(:hour) * hour +
|
436
|
+
RelativeTime.units_in_seconds.fetch(:minute) * minute +
|
437
|
+
second
|
438
|
+
|
439
|
+
if @seconds >= RelativeTime.units_in_seconds.fetch(:day)
|
440
|
+
raise TimeOutOfBoundsError
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
# Returns the time of the WallClock on a date
|
445
|
+
# @param [Date] date The date to apply the time on
|
446
|
+
# @return [Time] The time after the given date
|
447
|
+
# @example yesterday at 5:00
|
448
|
+
# time = WallClock.new(5, 00, :pm)
|
449
|
+
# time.on(Date.yesterday)
|
450
|
+
# => 2000-1-1 17:00:00 -0800
|
451
|
+
def on(date)
|
452
|
+
date.to_date.to_time + @seconds
|
453
|
+
end
|
454
|
+
|
455
|
+
# Comparse two {WallClock}s.
|
456
|
+
# @return [Boolean] True if the WallClocks are identical
|
457
|
+
def ==(time)
|
458
|
+
if time.is_a? WallClock
|
459
|
+
self.in_seconds == time.in_seconds
|
460
|
+
else
|
461
|
+
false
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
# Get the time of the WallClock, in seconds
|
466
|
+
# @return [Fixnum] The total time of the WallClock, in seconds
|
467
|
+
def in_seconds
|
468
|
+
@seconds
|
469
|
+
end
|
470
|
+
|
471
|
+
# Get the time of the WallClock, in minutes
|
472
|
+
# @return [Fixnum] The total time of the WallClock, in minutes
|
473
|
+
def in_minutes
|
474
|
+
@seconds / RelativeTime.units_in_seconds[:minute]
|
475
|
+
end
|
476
|
+
|
477
|
+
# Get the time of the WallClock, in hours
|
478
|
+
# @return [Fixnum] The total time of the WallClock, in hours
|
479
|
+
def in_hours
|
480
|
+
@seconds / RelativeTime.units_in_seconds[:hour]
|
481
|
+
end
|
482
|
+
|
483
|
+
# Get the second of the WallClock.
|
484
|
+
# @return [Fixnum] The second component of the WallClock
|
485
|
+
def second
|
486
|
+
self.to_relative.seconds
|
487
|
+
end
|
488
|
+
|
489
|
+
# Get the minute of the WallClock.
|
490
|
+
# @return [Fixnum] The minute component of the WallClock
|
491
|
+
def minute
|
492
|
+
self.to_relative.minutes
|
493
|
+
end
|
494
|
+
|
495
|
+
# Get the hour of the WallClock.
|
496
|
+
# @param [Symbol] system The houring system to use (either `:twelve_hour` or `:twenty_four_hour`; default `:twenty_four_hour`)
|
497
|
+
# @return [Fixnum] The hour component of the WallClock
|
498
|
+
def hour(system = :twenty_four_hour)
|
499
|
+
hour = self.to_relative.hours
|
500
|
+
if (system == :twelve_hour) && hour > 12
|
501
|
+
hour - 12
|
502
|
+
elsif (system == :twenty_four_hour)
|
503
|
+
hour
|
504
|
+
else
|
505
|
+
raise ArgumentError, "system should be :twelve_hour or :twenty_four_hour"
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
# Get the meridiem of the WallClock.
|
510
|
+
# @return [Symbol] The meridiem (either `:am` or `:pm`)
|
511
|
+
def meridiem
|
512
|
+
if self.hour > 12
|
513
|
+
:pm
|
514
|
+
else
|
515
|
+
:am
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
# Converts self to {WallClock}
|
520
|
+
# @see Time#to_wall
|
521
|
+
def to_wall
|
522
|
+
self
|
523
|
+
end
|
524
|
+
|
525
|
+
# Converts {WallClock} to {RelativeTime}
|
526
|
+
# @return [RelativeTime] {WallClock} as {RelativeTime}
|
527
|
+
# @example
|
528
|
+
# time = WallClock.new(5, 30, :pm)
|
529
|
+
# time.to_relative
|
530
|
+
# => 5 hours, 30 minutes
|
531
|
+
def to_relative
|
532
|
+
@seconds.seconds
|
533
|
+
end
|
534
|
+
|
535
|
+
# Convert {WallClock} to a human-readable format.
|
536
|
+
# @param [Symbol] system The hour system to use (`:twelve_hour` or `:twenty_four_hour`; default `:twelve_hour`)
|
537
|
+
# @example
|
538
|
+
# time = WallClock.new(5, 37, :pm)
|
539
|
+
# time.to_s
|
540
|
+
# => "5:37:00 PM"
|
541
|
+
# time.to_s(:twenty_four_hour)
|
542
|
+
# => "17:37:00"
|
543
|
+
# @raise ArgumentError Argument isn't a proper system
|
544
|
+
def to_s(system = :twelve_hour)
|
545
|
+
if(system == :twelve_hour)
|
546
|
+
meridiem = self.meridiem.to_s.upcase
|
547
|
+
"#{self.hour(system)}:#{self.minute}:#{self.second} #{meridiem}"
|
548
|
+
elsif(system == :twenty_four_hour)
|
549
|
+
"#{self.hour(system)}:#{self.minute}:#{self.second}"
|
550
|
+
else
|
551
|
+
raise ArgumentError, "system should be :twelve_hour or :twenty_four_hour"
|
552
|
+
end
|
269
553
|
end
|
270
554
|
end
|
271
555
|
|
272
556
|
# {Time} class monkeywrenched with {RelativeTime} support.
|
273
557
|
class Time
|
274
|
-
|
275
|
-
|
558
|
+
# Represents an error where two times were expected to be in the future, but were in the past.
|
559
|
+
# @see #until
|
560
|
+
class TimeIsInThePastError < ArgumentError; end
|
561
|
+
# Represents an error where two times were expected to be in the past, but were in the future.
|
562
|
+
# @see #since
|
563
|
+
class TimeIsInTheFutureError < ArgumentError; end
|
276
564
|
|
277
565
|
add = instance_method(:+)
|
278
566
|
define_method(:+) do |time|
|
279
|
-
if
|
567
|
+
if time.is_a? RelativeTime
|
280
568
|
time.after(self)
|
281
569
|
else
|
282
570
|
add.bind(self).(time)
|
@@ -285,7 +573,7 @@ class Time
|
|
285
573
|
|
286
574
|
subtract = instance_method(:-)
|
287
575
|
define_method(:-) do |time|
|
288
|
-
if
|
576
|
+
if time.is_a? RelativeTime
|
289
577
|
time.before(self)
|
290
578
|
else
|
291
579
|
subtract.bind(self).(time)
|
@@ -302,13 +590,13 @@ class Time
|
|
302
590
|
# @see Time#since
|
303
591
|
# @see Time#between
|
304
592
|
def self.until(time)
|
305
|
-
raise
|
593
|
+
raise TimeIsInThePastError if Time.now > time.to_time
|
306
594
|
|
307
595
|
Time.between(Time.now, time)
|
308
596
|
end
|
309
597
|
|
310
598
|
# Calculates the time since a given time
|
311
|
-
# @param [Time]
|
599
|
+
# @param [Time] time The time to calculate since now
|
312
600
|
# @return [RelativeTime] The time since the provided time
|
313
601
|
# @raise[TimeIsInTheFutureException] The provided time is in the future
|
314
602
|
# @example
|
@@ -317,7 +605,7 @@ class Time
|
|
317
605
|
# @see Time#since
|
318
606
|
# @see Time#between
|
319
607
|
def self.since(time)
|
320
|
-
raise
|
608
|
+
raise TimeIsInTheFutureError if time.to_time > Time.now
|
321
609
|
|
322
610
|
Time.between(Time.now, time)
|
323
611
|
end
|
@@ -352,6 +640,17 @@ class Time
|
|
352
640
|
def to_time
|
353
641
|
self
|
354
642
|
end
|
643
|
+
|
644
|
+
# Converts {Time} to {WallClock}
|
645
|
+
# @return [WallClock] {Time} as {WallClock}
|
646
|
+
# @example
|
647
|
+
# time = Time.now.to_wall
|
648
|
+
# Date.tomorrow.at(time)
|
649
|
+
# => 2000-1-2 13:13:27 -0800
|
650
|
+
# # "Same time tomorrow?"
|
651
|
+
def to_wall
|
652
|
+
WallClock.new(self.hour, self.min, self.sec)
|
653
|
+
end
|
355
654
|
end
|
356
655
|
|
357
656
|
# {Date} class monkeywrenched with {RelativeTime} helpers.
|
@@ -377,6 +676,14 @@ class Date
|
|
377
676
|
self
|
378
677
|
end
|
379
678
|
|
679
|
+
# Apply a time to a date
|
680
|
+
# @example yesterday at 5:00
|
681
|
+
# Date.yesterday.at(WallClock.new(5, 00, :pm))
|
682
|
+
# => 2000-1-1 17:00:00 -0800
|
683
|
+
def at(time)
|
684
|
+
time.to_wall.on(self)
|
685
|
+
end
|
686
|
+
|
380
687
|
# Return tomorrow as {Date}.
|
381
688
|
# @see Date#yesterday
|
382
689
|
def self.tomorrow
|
@@ -394,10 +701,9 @@ end
|
|
394
701
|
# @example
|
395
702
|
# 5.minutes
|
396
703
|
# => 5 minutes
|
397
|
-
# @see RelativeTime
|
704
|
+
# @see {RelativeTime#units}
|
398
705
|
class Fixnum
|
399
|
-
|
400
|
-
units.each do |unit, plural|
|
706
|
+
RelativeTime.units.each do |unit, plural|
|
401
707
|
define_method(unit) do |added_time = RelativeTime.new|
|
402
708
|
time = RelativeTime.new(self, unit)
|
403
709
|
time + added_time
|