class Timerizer::Duration::RoundedTime

Wraps rounding a {Timerizer::Duration} to the nearest value by the number of “places”, which are customary time units (seconds, minutes, hours, days, months, years, etc; decades and weeks are not included).

@private

Constants

DEFAULT_PLACES

Default “places” (units, e.g., hours/minutes) to use for rounding.

OMITTED_KEYS

Default {Timerizer::Duration::UNITS} not to include in rounded value.

ZERO_TIME

Initial value for adding a collection of Duration instances. (see sum_of)

Public Class Methods

call(duration, places = DEFAULT_PLACES, omitted_keys = OMITTED_KEYS) click to toggle source

Given an original {Timerizer::Duration} instance, return a new instance that “rounds” the duration to the closest value expressed in a certain number of units (default 2).

@param [{Timerizer::Duration}] duration Object encapsulating a duration

(in hours, minutes, etc) to "round" to a number of
units specified by `places`.

@param [Integer] places Number of units to include in rounded value.

Default is 2

@param [Array<Symbol>] omitted_keys Units to omit from calculation or

return value. Default is `[:decades, :weeks]`

@return {Timerizer::Duration} @example

t = (12.hours 16.minutes 47.seconds).ago
d = Time.since(t)
d2 = RoundedTime.call(d)
d.to_s  # => "12 hours, 16 minutes, 47 seconds"
d2.to_s # => "12 hours, 17 minutes"
# File lib/timerizer/duration/rounded_time.rb, line 46
def self.call(duration, places = DEFAULT_PLACES,
              omitted_keys = OMITTED_KEYS)
  new(duration, places, omitted_keys).call
end
new(duration, places = DEFAULT_PLACES, omitted_keys = OMITTED_KEYS) click to toggle source

Private initialiser to prevent direct instantiation by client code.

@param [{Timerizer::Duration}] duration Object encapsulating a duration

(in hours, minutes, etc) to "round" to a number of
units specified by `places`.

@param [Integer] places Number of units to include in rounded value.

Default is 2

@param [Array<Symbol>] omitted_keys Units to omit from calculation or

return value. Default is `[:decades, :weeks]`
# File lib/timerizer/duration/rounded_time.rb, line 77
def initialize(duration, places = DEFAULT_PLACES,
               omitted_keys = OMITTED_KEYS)
  @tt = TermTimes.new(duration, omitted_keys).call(places).freeze
end

Public Instance Methods

call() click to toggle source

High-level method to do calculations on component durations.

@return {Timerizer::Duration}

# File lib/timerizer/duration/rounded_time.rb, line 55
def call
  remainder = sum_of(remainder_times)
  sum_of(times) + offset_from(remainder)
end

Private Instance Methods

offset_from(remainder) click to toggle source

Determine whether returned {Timerizer::Duration} value should be rounded up or down based on a remainder value.

If the remainder value is more than half of the {#target_unit}, then this will return a duration of 1 times the target unit, else a duration of {ZERO_TIME}.

@return [{Timerizer::Duration}] Either zero or 1 times the `target_unit` @param [{Timerizer::Duration}] remainder Value of input duration less

than one `target_unit`
# File lib/timerizer/duration/rounded_time.rb, line 92
def offset_from(remainder)
  Timerizer::Duration.new((remainder * 2).to_units(target_unit))
end
sum_of(time_values) click to toggle source

Add all time (Duration) values in an Array (or other Enumerable).

@return [{Timerizer::Duration}] Sum total of input values. @param [Array<{Timerizer::Duration}>] Unit values to add together

# File lib/timerizer/duration/rounded_time.rb, line 101
def sum_of(time_values)
  time_values.inject(ZERO_TIME, :+)
end