Class: Nomad::Duration

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/nomad/duration.rb

Overview

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.

Examples:

Create a time duration

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

Convert a time to another format

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

Human print the time

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

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

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

Constant Summary collapse

NANO_SECOND =
Float(1)
MICRO_SECOND =
1_000 * NANO_SECOND
MILLI_SECOND =
1_000 * MICRO_SECOND
SECOND =
1_000 * MILLI_SECOND
MINUTE =
60 * SECOND
HOUR =
60 * MINUTE
DAY =
24 * HOUR
LABEL_NANO_SECOND =
"ns".freeze
LABEL_MICRO_SECOND =
"us".freeze
LABEL_MILLI_SECOND =
"ms".freeze
LABEL_SECOND =
"s".freeze
LABEL_MINUTE =
"m".freeze
LABEL_HOUR =
"h".freeze
LABEL_DAY =
"d".freeze
LABELS_MAP =
{
  LABEL_DAY          => DAY,
  LABEL_HOUR         => HOUR,
  LABEL_MINUTE       => MINUTE,
  LABEL_SECOND       => SECOND,
  LABEL_MILLI_SECOND => MILLI_SECOND,
  LABEL_MICRO_SECOND => MICRO_SECOND,
  LABEL_NANO_SECOND  => NANO_SECOND,
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(ns) ⇒ Duration

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

Examples:

Duration.new(1342902)

More human friendly

Duration.new(3*Duration::HOUR) # 3 hours


65
66
67
# File 'lib/nomad/duration.rb', line 65

def initialize(ns)
  @ns = Float(ns || 0)
end

Instance Method Details

#daysFloat

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

Examples:

duration.days #=> 42904289.248

Returns:

  • (Float)


142
143
144
# File 'lib/nomad/duration.rb', line 142

def days
  @ns / DAY
end

#hoursFloat

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

Examples:

duration.hours #=> 42904289.248

Returns:

  • (Float)


131
132
133
# File 'lib/nomad/duration.rb', line 131

def hours
  @ns / HOUR
end

#inspectObject



186
187
188
# 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

#microsecondsFloat

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

Examples:

duration.microseconds #=> 42904289.248

Returns:

  • (Float)


87
88
89
# File 'lib/nomad/duration.rb', line 87

def microseconds
  @ns / MICRO_SECOND
end

#millisecondsFloat

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

Examples:

duration.milliseconds #=> 42904289.248

Returns:

  • (Float)


98
99
100
# File 'lib/nomad/duration.rb', line 98

def milliseconds
  @ns / MILLI_SECOND
end

#minutesFloat

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

Examples:

duration.minutes #=> 42904289.248

Returns:

  • (Float)


120
121
122
# File 'lib/nomad/duration.rb', line 120

def minutes
  @ns / MINUTE
end

#nanosecondsFloat

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

Examples:

duration.nanoseconds #=> 32389042.0

Returns:

  • (Float)


76
77
78
# File 'lib/nomad/duration.rb', line 76

def nanoseconds
  @ns / NANO_SECOND
end

#secondsFloat

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

Examples:

duration.seconds #=> 42904289.248

Returns:

  • (Float)


109
110
111
# File 'lib/nomad/duration.rb', line 109

def seconds
  @ns / SECOND
end

#to_s(highest = LABEL_NANO_SECOND) ⇒ String

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.

Examples:

duration.to_s #=> "2d9h32m44s944ms429us193ns"

Limit to hours

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

Returns:

  • (String)


161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# 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