Class: SurrealDB::Duration

Inherits:
Object
  • Object
show all
Defined in:
lib/surrealdb/models/duration.rb

Overview

Represents a SurrealDB duration with second and nanosecond precision.

Constant Summary collapse

NANOS_PER_MICRO =
1_000
NANOS_PER_MILLI =
1_000_000
NANOS_PER_SECOND =
1_000_000_000
NANOS_PER_MINUTE =
NANOS_PER_SECOND * 60
NANOS_PER_HOUR =
NANOS_PER_MINUTE * 60
NANOS_PER_DAY =
NANOS_PER_HOUR * 24
NANOS_PER_WEEK =
NANOS_PER_DAY * 7
NANOS_PER_YEAR =
NANOS_PER_DAY * 365
UNIT_MAP =
{
  'y' => NANOS_PER_YEAR,
  'w' => NANOS_PER_WEEK,
  'd' => NANOS_PER_DAY,
  'h' => NANOS_PER_HOUR,
  'm' => NANOS_PER_MINUTE,
  's' => NANOS_PER_SECOND,
  'ms' => NANOS_PER_MILLI,
  'us' => NANOS_PER_MICRO,
  'µs' => NANOS_PER_MICRO,
  'ns' => 1
}.freeze
PARSE_REGEX =
/(\d+)(y|w|d|h|ms|m|us|µs|ns|s)/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(secs, nanos = 0) ⇒ Duration

Returns a new instance of Duration.

Parameters:

  • secs (Integer)
  • nanos (Integer) (defaults to: 0)


23
24
25
26
27
# File 'lib/surrealdb/models/duration.rb', line 23

def initialize(secs, nanos = 0)
  total_nanos = (secs * NANOS_PER_SECOND) + nanos
  @secs = total_nanos / NANOS_PER_SECOND
  @nanos = total_nanos % NANOS_PER_SECOND
end

Instance Attribute Details

#nanosInteger (readonly)

Returns nanosecond remainder (0..999_999_999).

Returns:

  • (Integer)

    nanosecond remainder (0..999_999_999)



19
20
21
# File 'lib/surrealdb/models/duration.rb', line 19

def nanos
  @nanos
end

#secsInteger (readonly)

Returns whole seconds.

Returns:

  • (Integer)

    whole seconds



16
17
18
# File 'lib/surrealdb/models/duration.rb', line 16

def secs
  @secs
end

Class Method Details

.parse(str) ⇒ Duration

Parses a SurrealDB duration string like "1h30m", "2d3h15m10s".

Parameters:

  • str (String)

Returns:

Raises:

  • (ArgumentError)


47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/surrealdb/models/duration.rb', line 47

def self.parse(str)
  total_nanos = 0
  matched = false

  str.to_s.scan(PARSE_REGEX) do |amount, unit|
    matched = true
    total_nanos += amount.to_i * UNIT_MAP.fetch(unit)
  end

  raise ArgumentError, "invalid duration: #{str}" unless matched

  new(total_nanos / NANOS_PER_SECOND, total_nanos % NANOS_PER_SECOND)
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



94
95
96
# File 'lib/surrealdb/models/duration.rb', line 94

def ==(other)
  other.is_a?(Duration) && other.secs == @secs && other.nanos == @nanos
end

#hashObject



99
100
101
# File 'lib/surrealdb/models/duration.rb', line 99

def hash
  [self.class, @secs, @nanos].hash
end

#inspectObject



90
91
92
# File 'lib/surrealdb/models/duration.rb', line 90

def inspect
  "SurrealDB::Duration(#{self})"
end

#to_fFloat

Returns total duration in seconds.

Returns:

  • (Float)

    total duration in seconds



62
63
64
# File 'lib/surrealdb/models/duration.rb', line 62

def to_f
  @secs + (@nanos.to_f / NANOS_PER_SECOND)
end

#to_sObject



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/surrealdb/models/duration.rb', line 71

def to_s
  return '0s' if @secs.zero? && @nanos.zero?

  remaining = total_nanos
  parts = []

  [['y', NANOS_PER_YEAR], ['w', NANOS_PER_WEEK], ['d', NANOS_PER_DAY],
   ['h', NANOS_PER_HOUR], ['m', NANOS_PER_MINUTE], ['s', NANOS_PER_SECOND],
   ['ms', NANOS_PER_MILLI], ['us', NANOS_PER_MICRO], ['ns', 1]].each do |unit, nanos_per|
    next if remaining < nanos_per

    count = remaining / nanos_per
    remaining %= nanos_per
    parts << "#{count}#{unit}"
  end

  parts.join
end

#total_nanosInteger

Returns total nanoseconds.

Returns:

  • (Integer)

    total nanoseconds



67
68
69
# File 'lib/surrealdb/models/duration.rb', line 67

def total_nanos
  (@secs * NANOS_PER_SECOND) + @nanos
end