class Nomad::Duration

Duration is a time extension to match Golang's number types. The raw underlying value is a float representing the number of nanoseconds. This class provides convenience functions for converting those durations into more meaningful numbers.

Note that the return type is always a float, even for time operations that convert evenly.

@example Create a time duration

time = 50*Duration::SECOND # 50 seconds
time = 1*Duration::MINUTE + 50*Duration::SECOND # 1 minute, 50 seconds

@example Convert a time to another format

time = 60*Duration::SECOND
time.minutes #=> 1.0

@example Human print the time

60*Duration::Second.to_s #=> "60s"
Duration.new(248902890389024).to_s #=> "2d21h8m22s890ms389us24ns"

@example Human print the time up to seconds, ignoring anything less that seconds

Duration.new(248902890389024).to_s(:s) #=> "2d21h8m22s"

Constants

DAY
HOUR
LABELS_MAP
LABEL_DAY
LABEL_HOUR
LABEL_MICRO_SECOND
LABEL_MILLI_SECOND
LABEL_MINUTE
LABEL_NANO_SECOND
LABEL_SECOND
MICRO_SECOND
MILLI_SECOND
MINUTE
NANO_SECOND
SECOND

Public Class Methods

new(ns) click to toggle source

Initialize accepts the numer of nanoseconds as an Integer or Float and builds the duration parsing around it.

@example

Duration.new(1342902)

@example More human friendly

Duration.new(3*Duration::HOUR) # 3 hours
# File lib/nomad/duration.rb, line 65
def initialize(ns)
  @ns = Float(ns || 0)
end

Public Instance Methods

days() click to toggle source

The complete number of days. Non-whole-days parts are represented as decimals.

@example

duration.days #=> 42904289.248

@return [Float]

# File lib/nomad/duration.rb, line 142
def days
  @ns / DAY
end
hours() click to toggle source

The complete number of hours. Non-whole-hours parts are represented as decimals.

@example

duration.hours #=> 42904289.248

@return [Float]

# File lib/nomad/duration.rb, line 131
def hours
  @ns / HOUR
end
inspect() click to toggle source
# File lib/nomad/duration.rb, line 186
def inspect
  "#<%s:0x%s %s>" % [self.class, (object_id << 1).to_s(16), "@duration=\"#{to_s}\""]
end
microseconds() click to toggle source

The complete number of microseconds. Non-whole-microseconds parts are represented as decimals.

@example

duration.microseconds #=> 42904289.248

@return [Float]

# File lib/nomad/duration.rb, line 87
def microseconds
  @ns / MICRO_SECOND
end
milliseconds() click to toggle source

The complete number of milliseconds. Non-whole-milliseconds parts are represented as decimals.

@example

duration.milliseconds #=> 42904289.248

@return [Float]

# File lib/nomad/duration.rb, line 98
def milliseconds
  @ns / MILLI_SECOND
end
minutes() click to toggle source

The complete number of minutes. Non-whole-minutes parts are represented as decimals.

@example

duration.minutes #=> 42904289.248

@return [Float]

# File lib/nomad/duration.rb, line 120
def minutes
  @ns / MINUTE
end
nanoseconds() click to toggle source

The complete number of nanoseconds. This will always be a whole number, but the return type is a float for easier chaining and consistency.

@example

duration.nanoseconds #=> 32389042.0

@return [Float]

# File lib/nomad/duration.rb, line 76
def nanoseconds
  @ns / NANO_SECOND
end
seconds() click to toggle source

The complete number of seconds. Non-whole-seconds parts are represented as decimals.

@example

duration.seconds #=> 42904289.248

@return [Float]

# File lib/nomad/duration.rb, line 109
def seconds
  @ns / SECOND
end
to_s(highest = LABEL_NANO_SECOND) click to toggle source

The “human-friendly” form of this duration. By default, the time is displayed up to the total number of nanoseconds, with each part maximized before continuing to the smallest part (i.e. 24h becomes 1d). Fields with zero value are omitted.

An optional “highest label” may be supplied to limit the output to a particular label.

@example

duration.to_s #=> "2d9h32m44s944ms429us193ns"

@example Limit to hours

duration.to_s(:h) #=> "2d9h"

@return [String]

# File lib/nomad/duration.rb, line 161
def to_s(highest = LABEL_NANO_SECOND)
  highest = highest.to_s if !highest.is_a?(String)
  if !LABELS_MAP.key?(highest)
    raise "Invalid label `#{highest}'!"
  end

  t, str, negative = @ns, "", false
  if t < 0
    t *= -1
    negative = true
  end

  LABELS_MAP.each do |l,c|
    if (item = (t / c).floor(0)) > 0
      str << String(item) << l
      t -= (item * c)
    end
    break if l == highest
  end

  return "0" << highest if str.empty?
  return "-" << str if negative
  return str
end