class Sequel::Postgres::IntervalDatabaseMethods::Parser

Creates callable objects that convert strings into ActiveSupport::Duration instances.

Constants

SECONDS_PER_MONTH
SECONDS_PER_YEAR
USE_PARTS_ARRAY

Whether ActiveSupport::Duration.new takes parts as array instead of hash

Public Instance Methods

call(string) click to toggle source

Parse the interval input string into an ActiveSupport::Duration instance.

# File lib/sequel/extensions/pg_interval.rb, line 85
def call(string)
  raise(InvalidValue, "invalid or unhandled interval format: #{string.inspect}") unless matches = /\A([+-]?\d+ years?\s?)?([+-]?\d+ mons?\s?)?([+-]?\d+ days?\s?)?(?:(?:([+-])?(\d{2,10}):(\d\d):(\d\d(\.\d+)?))|([+-]?\d+ hours?\s?)?([+-]?\d+ mins?\s?)?([+-]?\d+(\.\d+)? secs?\s?)?)?\z/.match(string)

  value = 0
  parts = {}

  if v = matches[1]
    v = v.to_i
    value += SECONDS_PER_YEAR * v
    parts[:years] = v
  end
  if v = matches[2]
    v = v.to_i
    value += SECONDS_PER_MONTH * v
    parts[:months] = v
  end
  if v = matches[3]
    v = v.to_i
    value += 86400 * v
    parts[:days] = v
  end
  if matches[5]
    seconds = matches[5].to_i * 3600 + matches[6].to_i * 60
    seconds += matches[8] ? matches[7].to_f : matches[7].to_i
    seconds *= -1 if matches[4] == '-'
    value += seconds
    parts[:seconds] = seconds
  elsif matches[9] || matches[10] || matches[11]
    seconds = 0
    if v = matches[9]
      seconds += v.to_i * 3600
    end
    if v = matches[10]
      seconds += v.to_i * 60
    end
    if v = matches[11]
      seconds += matches[12] ? v.to_f : v.to_i
    end
    value += seconds
    parts[:seconds] = seconds
  end

  # :nocov:
  if USE_PARTS_ARRAY
    parts = parts.to_a
  end
  # :nocov:

  ActiveSupport::Duration.new(value, parts)
end