class Monotime::Duration

A type representing a span of time in nanoseconds.

Constants

DIVISORS

Public Class Methods

from_micros(micros) click to toggle source

Generate a new Duration measuring the given number of microseconds.

@param micros [Numeric] @return [Duration]

# File lib/monotime/duration.rb, line 44
def from_micros(micros)
  new(Integer(micros * 1_000))
end
Also aliased as: micros
from_millis(millis) click to toggle source

Generate a new Duration measuring the given number of milliseconds.

@param millis [Numeric] @return [Duration]

# File lib/monotime/duration.rb, line 34
def from_millis(millis)
  new(Integer(millis * 1_000_000))
end
Also aliased as: millis
from_nanos(nanos) click to toggle source

Generate a new Duration measuring the given number of nanoseconds.

@param nanos [Numeric] @return [Duration]

# File lib/monotime/duration.rb, line 54
def from_nanos(nanos)
  new(Integer(nanos))
end
Also aliased as: nanos
from_secs(secs) click to toggle source

Generate a new Duration measuring the given number of seconds.

@param secs [Numeric] @return [Duration]

# File lib/monotime/duration.rb, line 24
def from_secs(secs)
  new(Integer(secs * 1_000_000_000))
end
Also aliased as: secs
measure() { || ... } click to toggle source

Return a Duration measuring the elapsed time of the yielded block.

@example

Duration.measure { sleep(0.5) }.to_s # => "512.226109ms"

@return [Duration]

# File lib/monotime/duration.rb, line 66
def measure
  Instant.now.tap { yield }.elapsed
end
micros(micros)
Alias for: from_micros
millis(millis)
Alias for: from_millis
nanos(nanos)
Alias for: from_nanos
new(nanos = 0) click to toggle source

Create a new Duration of a specified number of nanoseconds, zero by default.

Users are strongly advised to use #from_nanos instead.

@param nanos [Integer] @see from_nanos

# File lib/monotime/duration.rb, line 15
def initialize(nanos = 0)
  @ns = Integer(nanos)
end
secs(secs)
Alias for: from_secs
with_measure() { || ... } click to toggle source

Return the result of the yielded block alongside a Duration.

@example

Duration.with_measure { "bloop" } # => ["bloop", #<Monotime::Duration: ...>]

@return [Object, Duration]

# File lib/monotime/duration.rb, line 76
def with_measure
  start = Instant.now
  ret = yield
  [ret, start.elapsed]
end

Public Instance Methods

*(other) click to toggle source

Multiply this duration by a Numeric.

@example

(Duration.from_secs(10) * 2).to_s # => "20s"

@param [Numeric] @return [Duration]

# File lib/monotime/duration.rb, line 129
def *(other)
  Duration.new(to_nanos * other)
end
+(other) click to toggle source

Add another Duration or #to_nanos-coercible object to this one, returning a new Duration.

@example

(Duration.from_secs(10) + Duration.from_secs(5)).to_s # => "15s"

@param [Duration, to_nanos] @return [Duration]

# File lib/monotime/duration.rb, line 91
def +(other)
  raise TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos)

  Duration.new(to_nanos + other.to_nanos)
end
-(other) click to toggle source

Subtract another Duration or #to_nanos-coercible object from this one, returning a new Duration.

@example

(Duration.from_secs(10) - Duration.from_secs(5)).to_s # => "5s"

@param [Duration, to_nanos] @return [Duration]

# File lib/monotime/duration.rb, line 105
def -(other)
  raise TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos)

  Duration.new(to_nanos - other.to_nanos)
end
-@() click to toggle source

Unary minus: make a positive Duration negative, and vice versa.

@example

-Duration.from_secs(-1).to_s # => "1s"
-Duration.from_secs(1).to_s  # => "-1s"

@return [Duration]

# File lib/monotime/duration.rb, line 140
def -@
  Duration.new(-to_nanos)
end
/(other) click to toggle source

Divide this duration by a Numeric.

@example

(Duration.from_secs(10) / 2).to_s # => "5s"

@param [Numeric] @return [Duration]

# File lib/monotime/duration.rb, line 118
def /(other)
  Duration.new(to_nanos / other)
end
<=>(other) click to toggle source

Compare the value of this Duration with another, or any #to_nanos-coercible object, or nil if not comparable.

@param [Duration, to_nanos, Object] @return [-1, 0, 1, nil]

# File lib/monotime/duration.rb, line 162
def <=>(other)
  to_nanos <=> other.to_nanos if other.respond_to?(:to_nanos)
end
==(other) click to toggle source

Compare the equality of the value of this Duration with another, or any #to_nanos-coercible object, or nil if not comparable.

@param [Duration, to_nanos, Object] @return [Boolean]

# File lib/monotime/duration.rb, line 171
def ==(other)
  other.respond_to?(:to_nanos) && to_nanos == other.to_nanos
end
abs() click to toggle source

Return a Duration that's absolute (positive).

@example

Duration.from_secs(-1).abs.to_s # => "1s"
Duration.from_secs(1).abs.to_s  # => "1s"

@return [Duration]

# File lib/monotime/duration.rb, line 151
def abs
  return self if positive? || zero?

  Duration.new(to_nanos.abs)
end
eql?(other) click to toggle source

Check equality of the value and type of this Duration with another.

@param [Duration, Object] @return [Boolean]

# File lib/monotime/duration.rb, line 179
def eql?(other)
  other.is_a?(Duration) && to_nanos == other.to_nanos
end
hash() click to toggle source

Generate a hash for this type and value.

@return [Integer]

# File lib/monotime/duration.rb, line 186
def hash
  self.class.hash ^ to_nanos.hash
end
micros()
Alias for: to_micros
millis()
Alias for: to_millis
nanos()
Alias for: to_nanos
negative?() click to toggle source

Return true if this Duration is negative.

@return [Boolean]

# File lib/monotime/duration.rb, line 236
def negative?
  to_nanos.negative?
end
nonzero?() click to toggle source

Return true if this Duration is non-zero.

@return [Boolean]

# File lib/monotime/duration.rb, line 250
def nonzero?
  to_nanos.nonzero?
end
positive?() click to toggle source

Return true if this Duration is positive.

@return [Boolean]

# File lib/monotime/duration.rb, line 229
def positive?
  to_nanos.positive?
end
secs()
Alias for: to_secs
sleep() click to toggle source

Sleep for the duration of this Duration. Equivalent to +Kernel.sleep(duration.to_secs)+.

@example

Duration.from_secs(1).sleep  # => 1
Duration.from_secs(-1).sleep # => raises NotImplementedError

@raise [NotImplementedError] negative Duration sleeps are not yet supported. @return [Integer] @see Instant#sleep

# File lib/monotime/duration.rb, line 264
def sleep
  raise NotImplementedError, 'time travel module missing' if negative?

  Kernel.sleep(to_secs)
end
to_micros() click to toggle source

Return this Duration in microseconds.

@return [Float]

# File lib/monotime/duration.rb, line 211
def to_micros
  to_nanos / 1_000.0
end
Also aliased as: micros
to_millis() click to toggle source

Return this Duration in milliseconds.

@return [Float]

# File lib/monotime/duration.rb, line 202
def to_millis
  to_nanos / 1_000_000.0
end
Also aliased as: millis
to_nanos() click to toggle source

Return this Duration in nanoseconds.

@return [Integer]

# File lib/monotime/duration.rb, line 220
def to_nanos
  @ns
end
Also aliased as: nanos
to_s(precision = 9) click to toggle source

Format this Duration into a human-readable string, with a given number of decimal places.

The exact format is subject to change, users with specific requirements are encouraged to use their own formatting methods.

@example

Duration.from_nanos(100).to_s  # => "100ns"
Duration.from_micros(100).to_s # => "100μs"
Duration.from_millis(100).to_s # => "100ms"
Duration.from_secs(100).to_s   # => "100s"
Duration.from_nanos(1234567).to_s # => "1.234567ms"
Duration.from_nanos(1234567).to_s(2) # => "1.23ms"

@param precision [Integer] the maximum number of decimal places @return [String]

# File lib/monotime/duration.rb, line 295
def to_s(precision = 9)
  precision = Integer(precision).abs
  div, unit = DIVISORS.find { |d, _| to_nanos.abs >= d }

  if div.zero?
    format('%d%s', to_nanos, unit)
  else
    format("%#.#{precision}f", to_nanos / div).sub(/\.?0*\z/, '') << unit
  end
end
to_secs() click to toggle source

Return this Duration in seconds.

@return [Float]

# File lib/monotime/duration.rb, line 193
def to_secs
  to_nanos / 1_000_000_000.0
end
Also aliased as: secs
zero?() click to toggle source

Return true if this Duration is zero.

@return [Boolean]

# File lib/monotime/duration.rb, line 243
def zero?
  to_nanos.zero?
end