class Monotime::Instant
A measurement from the operating system's monotonic clock, with up to nanosecond precision.
Attributes
A measurement, in nanoseconds. Should be considered opaque and non-portable outside the process that created it.
Public Class Methods
Create a new Instant
from an optional nanosecond measurement.
Users should generally not pass anything to this function.
@param nanos [Integer] @see now
# File lib/monotime/instant.rb, line 20 def initialize(nanos = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)) @ns = Integer(nanos) end
An alias to new
, and generally preferred over it.
@return [Instant]
# File lib/monotime/instant.rb, line 27 def self.now new end
Public Instance Methods
Add a Duration
or #to_nanos
-coercible object to this Instant
, returning a new Instant
.
@example
(Instant.now + Duration.from_secs(1)).to_s # => "-999.983976ms"
@param other [Duration, to_nanos] @return [Instant]
# File lib/monotime/instant.rb, line 126 def +(other) return TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos) Instant.new(@ns + other.to_nanos) end
Subtract another Instant
to generate a Duration
between the two, or a Duration
or #to_nanos
-coercible object, to generate an Instant
offset by it.
@example
(Instant.now - Duration.from_secs(1)).to_s # => "1.000016597s" (Instant.now - Instant.now).to_s # => "-3.87μs"
@param other [Instant, Duration
, to_nanos] @return [Duration, Instant]
# File lib/monotime/instant.rb, line 142 def -(other) if other.is_a?(Instant) Duration.new(@ns - other.ns) elsif other.respond_to?(:to_nanos) Instant.new(@ns - other.to_nanos) else raise TypeError, 'Not one of: [Instant, Duration, #to_nanos]' end end
Determine if the given Instant
is before, equal to or after this one. nil
if not passed an Instant
.
@return [-1, 0, 1, nil]
# File lib/monotime/instant.rb, line 156 def <=>(other) @ns <=> other.ns if other.is_a?(Instant) end
Determine if other
's value equals that of this Instant
. Use eql?
if type checks are desired for future compatibility.
@return [Boolean] @see eql?
# File lib/monotime/instant.rb, line 165 def ==(other) other.is_a?(Instant) && @ns == other.ns end
Return a Duration
between this Instant
and another.
@param earlier [Instant] @return [Duration]
# File lib/monotime/instant.rb, line 35 def duration_since(earlier) raise TypeError, 'Not an Instant' unless earlier.is_a?(Instant) earlier - self end
Return a Duration
since this Instant
and now.
@return [Duration]
# File lib/monotime/instant.rb, line 44 def elapsed duration_since(self.class.now) end
Generate a hash for this type and value.
@return [Integer]
# File lib/monotime/instant.rb, line 174 def hash self.class.hash ^ @ns.hash end
Return whether this Instant
is in the future.
@return [Boolean]
# File lib/monotime/instant.rb, line 60 def in_future? elapsed.negative? end
Return whether this Instant
is in the past.
@return [Boolean]
# File lib/monotime/instant.rb, line 51 def in_past? elapsed.positive? end
Sleep until this Instant
, plus an optional Duration
, returning a Duration
that's either positive if any time was slept, or negative if sleeping would require time travel.
@example Sleeps for a second
start = Instant.now sleep 0.5 # do stuff for half a second start.sleep(Duration.from_secs(1)).to_s # => "490.088706ms" (slept) start.sleep(Duration.from_secs(1)).to_s # => "-12.963502ms" (did not sleep)
@example Also sleeps for a second.
one_second_in_the_future = Instant.now + Duration.from_secs(1) one_second_in_the_future.sleep.to_s # => "985.592712ms" (slept) one_second_in_the_future.sleep.to_s # => "-4.71217ms" (did not sleep)
@param duration [nil, Duration
, to_nanos] @return [Duration] the slept duration, if #positive?
, else the overshot time
# File lib/monotime/instant.rb, line 83 def sleep(duration = nil) remaining = duration ? duration - elapsed : -elapsed remaining.tap { |rem| rem.sleep if rem.positive? } end
Sleep for the given number of milliseconds past this Instant
, if any.
Equivalent to +#sleep(Duration.from_millis(millis)
)+
@param millis [Numeric] number of milliseconds to sleep past this Instant
@return [Duration] the slept duration, if #positive?
, else the overshot time @see sleep
# File lib/monotime/instant.rb, line 107 def sleep_millis(millis) sleep(Duration.from_millis(millis)) end
Sleep for the given number of seconds past this Instant
, if any.
Equivalent to +#sleep(Duration.from_secs(secs)
)+
@param secs [Numeric] number of seconds to sleep past this Instant
@return [Duration] the slept duration, if #positive?
, else the overshot time @see sleep
# File lib/monotime/instant.rb, line 96 def sleep_secs(secs) sleep(Duration.from_secs(secs)) end
Sugar for #elapsed.to_s
.
@see Duration#to_s
# File lib/monotime/instant.rb, line 114 def to_s(*args) elapsed.to_s(*args) end