Class: Sequel::Postgres::IntervalDatabaseMethods::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/sequel/extensions/pg_interval.rb

Overview

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

Instance Method Summary collapse

Instance Method Details

#call(string) ⇒ Object

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

Raises:

  • (InvalidValue)

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/sequel/extensions/pg_interval.rb', line 65

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 += 31557600 * v
    parts << [:years, v]
  end
  if v = matches[2]
    v = v.to_i
    value += 2592000 * 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

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