Class: RelativeTime
- Inherits:
-
Object
- Object
- RelativeTime
- Defined in:
- lib/timerizer.rb
Overview
Represents a relative amount of time. For example, ‘`5 days`’, ‘`4 years`’, and ‘`5 years, 4 hours, 3 minutes, 2 seconds`’ are all RelativeTimes.
Constant Summary collapse
- @@units =
{ :second => :seconds, :minute => :minutes, :hour => :hours, :day => :days, :week => :weeks, :month => :months, :year => :years, :decade => :decades, :century => :centuries, :millennium => :millennia }
- @@in_seconds =
{ :second => 1, :minute => 60, :hour => 3600, :day => 86400, :week => 604800 }
- @@in_months =
{ :month => 1, :year => 12, :decade => 120, :century => 1200, :millennium => 12000 }
- @@average_seconds =
Average amount of time in a given unit. Used internally within the #average and #unaverage methods.
{ :month => 2629746, :year => 31556952 }
- @@syntaxes =
Default syntax formats that can be used with #to_s
{ :micro => { :units => { :seconds => 's', :minutes => 'm', :hours => 'h', :days => 'd', :weeks => 'w', :months => 'mn', :years => 'y', }, :separator => '', :delimiter => ' ', :count => 1 }, :short => { :units => { :seconds => 'sec', :minutes => 'min', :hours => 'hr', :days => 'd', :weeks => 'wk', :months => 'mn', :years => 'yr', :centuries => 'ct', :millenia => 'ml' }, :separator => '', :delimiter => ' ', :count => 2 }, :long => { :units => { :seconds => ['second', 'seconds'], :minutes => ['minute', 'minutes'], :hours => ['hour', 'hours'], :days => ['day', 'days'], :weeks => ['week', 'weeks'], :months => ['month', 'months'], :years => ['year', 'years'], :centuries => ['century', 'centuries'], :millennia => ['millenium', 'millenia'], } } }
Class Method Summary collapse
-
.units ⇒ Object
All potential units.
-
.units_in_months ⇒ Object
Unit values in months.
-
.units_in_seconds ⇒ Object
Unit values in seconds.
Instance Method Summary collapse
-
#+(time) ⇒ Object
Add two RelativeTimes together.
-
#-(time) ⇒ Object
Find the difference between two RelativeTimes.
-
#==(time) ⇒ Boolean
Compares two RelativeTimes to determine if they are equal.
-
#after(time) ⇒ Time
Return the time after the given time according to the current RelativeTime.
-
#ago ⇒ Time
Return the time between the RelativeTime and the current time.
-
#average ⇒ RelativeTime
Average second-based units to month-based units.
-
#average! ⇒ Object
Destructively average second-based units to month-based units.
-
#before(time) ⇒ Time
Determines the time between RelativeTime and the given time.
-
#from_now ⇒ Time
Return the time after the current time and the RelativeTime.
-
#get(unit) ⇒ Integer
Return the number of base units in a RelativeTime.
-
#initialize(count = 0, unit = :second) ⇒ RelativeTime
constructor
Initialize a new instance of RelativeTime.
-
#to_s(syntax = :long) ⇒ Object
Convert RelativeTime to a human-readable format.
-
#to_wall ⇒ WallClock
Converts RelativeTime to WallClock.
-
#unaverage ⇒ RelativeTime
Average month-based units to second-based units.
-
#unaverage! ⇒ Object
Destructively average month-based units to second-based units.
Constructor Details
#new(hash) ⇒ RelativeTime #new(count, unit) ⇒ RelativeTime
Initialize a new instance of RelativeTime.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/timerizer.rb', line 111 def initialize(count = 0, unit = :second) if count.is_a? Hash units = count units.default = 0 @seconds, @months = units.values_at(:seconds, :months) else @seconds = @months = 0 if @@in_seconds.has_key?(unit) @seconds = count * @@in_seconds.fetch(unit) elsif @@in_months.has_key?(unit) @months = count * @@in_months.fetch(unit) end end end |
Class Method Details
.units ⇒ Object
All potential units. Key is the unit name, and the value is its plural form.
89 90 91 |
# File 'lib/timerizer.rb', line 89 def self.units @@units end |
.units_in_months ⇒ Object
Unit values in months. If a unit is not present in this hash, it is assumed to be in the @@in_seconds hash.
99 100 101 |
# File 'lib/timerizer.rb', line 99 def self.units_in_months @@in_months end |
.units_in_seconds ⇒ Object
Unit values in seconds. If a unit is not present in this hash, it is assumed to be in the @@in_months hash.
94 95 96 |
# File 'lib/timerizer.rb', line 94 def self.units_in_seconds @@in_seconds end |
Instance Method Details
#+(time) ⇒ Object
Add two RelativeTimes together.
312 313 314 315 316 317 318 |
# File 'lib/timerizer.rb', line 312 def +(time) raise ArgumentError unless time.is_a?(RelativeTime) RelativeTime.new({ :seconds => @seconds + time.get(:seconds), :months => @months + time.get(:months) }) end |
#-(time) ⇒ Object
Find the difference between two RelativeTimes.
323 324 325 326 327 328 329 |
# File 'lib/timerizer.rb', line 323 def -(time) raise ArgumentError unless time.is_a?(RelativeTime) RelativeTime.new({ :seconds => @seconds - time.get(:seconds), :months => @months - time.get(:months) }) end |
#==(time) ⇒ Boolean
Be weary of rounding; this method compares both RelativeTimes’ base units
Compares two RelativeTimes to determine if they are equal
131 132 133 134 135 136 137 |
# File 'lib/timerizer.rb', line 131 def ==(time) if time.is_a?(RelativeTime) @seconds == time.get(:seconds) && @months == time.get(:months) else false end end |
#after(time) ⇒ Time
Return the time after the given time according to the current RelativeTime.
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/timerizer.rb', line 195 def after(time) time = time.to_time + @seconds new_year = time.year + self.years new_month = time.month + self.months while new_month > 12 new_year += 1 new_month -= 12 end if Date.valid_date?(new_year, new_month, time.day) new_day = time.day else new_day = Date.new(new_year, new_month).days_in_month end new_time = Time.new( new_year, new_month, new_day, time.hour, time.min, time.sec ) Time.at(new_time.to_i, time.nsec/1000.0) end |
#ago ⇒ Time
Return the time between the RelativeTime and the current time.
187 188 189 |
# File 'lib/timerizer.rb', line 187 def ago self.before(Time.now) end |
#average ⇒ RelativeTime
Average second-based units to month-based units.
265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/timerizer.rb', line 265 def average if @seconds > 0 months = (@seconds / @@average_seconds[:month]) seconds = @seconds - months.months.unaverage.get(:seconds) RelativeTime.new( :seconds => seconds, :months => months + @months ) else self end end |
#average! ⇒ Object
Destructively average second-based units to month-based units.
280 281 282 283 284 285 |
# File 'lib/timerizer.rb', line 280 def average! averaged = self.average @seconds = averaged.get(:seconds) @months = averaged.get(:months) self end |
#before(time) ⇒ Time
Determines the time between RelativeTime and the given time.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/timerizer.rb', line 162 def before(time) time = time.to_time - @seconds new_month = time.month - self.months new_year = time.year - self.years while new_month < 1 new_month += 12 new_year -= 1 end if Date.valid_date?(new_year, new_month, time.day) new_day = time.day else new_day = Date.new(new_year, new_month).days_in_month end new_time = Time.new( new_year, new_month, new_day, time.hour, time.min, time.sec ) Time.at(new_time.to_i, time.nsec/1000) end |
#from_now ⇒ Time
Return the time after the current time and the RelativeTime.
220 221 222 |
# File 'lib/timerizer.rb', line 220 def from_now self.after(Time.now) end |
#get(unit) ⇒ Integer
Return the number of base units in a RelativeTime.
143 144 145 146 147 148 149 150 151 |
# File 'lib/timerizer.rb', line 143 def get(unit) if unit == :seconds @seconds elsif unit == :months @months else raise ArgumentError end end |
#to_s(syntax) ⇒ Object #to_s(hash) ⇒ Object
Convert RelativeTime to a human-readable format.
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 |
# File 'lib/timerizer.rb', line 358 def to_s(syntax = :long) if syntax.is_a? Symbol syntax = @@syntaxes.fetch(syntax) end raise ArgumentError unless syntax.is_a? Hash times = [] if syntax[:count].nil? || syntax[:count] == :all syntax[:count] = @@units.count end units = syntax.fetch(:units) count = 0 units = Hash[units.to_a.reverse] units.each do |unit, (singular, plural)| if count < syntax.fetch(:count) time = self.respond_to?(unit) ? self.send(unit) : 0 if time > 1 && !plural.nil? times << [time, plural] count += 1 elsif time > 0 times << [time, singular] count += 1 end end end times.map do |time| time.join(syntax[:separator] || ' ') end.join(syntax[:delimiter] || ', ') end |
#to_wall ⇒ WallClock
Converts RelativeTime to WallClock
336 337 338 339 |
# File 'lib/timerizer.rb', line 336 def to_wall raise WallClock::TimeOutOfBoundsError if @months > 0 WallClock.new(:second => @seconds) end |
#unaverage ⇒ RelativeTime
Average month-based units to second-based units.
294 295 296 297 298 |
# File 'lib/timerizer.rb', line 294 def unaverage seconds = @@average_seconds[:month] * @months seconds += @seconds RelativeTime.new(:seconds => seconds) end |
#unaverage! ⇒ Object
Destructively average month-based units to second-based units.
302 303 304 305 306 307 |
# File 'lib/timerizer.rb', line 302 def unaverage! unaveraged = self.average @seconds = unaverage.get(:seconds) @months = unaverage.get(:months) self end |