Class: Quack::Types::Time

Inherits:
Quack::Type show all
Defined in:
lib/quack/types/time.rb

Constant Summary collapse

YMD_FORMAT =
/\A
  (?<year>\d{4})(-|\/)
  (?<month>\d{2})(-|\/)
  (?<day>\d{2})
\z/x
ISO_8601 =
/\A
  (?<year>\d{4})-
  (?<month>\d{2})-
  (?<day>\d{2})T
  (?<hour>\d{2}):
  (?<minute>\d{2}):
  (?<second>\d{2})
  (?<offset>Z|(\+|-)(\d{2}):(\d{2}))
\z/x
UTC =
"+00:00"

Instance Attribute Summary

Attributes inherited from Quack::Type

#value

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Quack::Type

#already_coerced?, already_coerced?, #initialize, #type_matches?

Constructor Details

This class inherits a constructor from Quack::Type

Class Method Details

.built_in_typesObject



26
27
28
# File 'lib/quack/types/time.rb', line 26

def built_in_types
  [::Time]
end

.iso_8601?(value) ⇒ Boolean

Returns:



30
31
32
# File 'lib/quack/types/time.rb', line 30

def iso_8601?(value)
  !!(value.to_s.strip =~ ISO_8601)
end

.matches?(value) ⇒ Boolean

Returns:



38
39
40
# File 'lib/quack/types/time.rb', line 38

def matches?(value)
  already_coerced?(value) || iso_8601?(value) || ymd?(value)
end

.ymd?(value) ⇒ Boolean

Returns:



34
35
36
# File 'lib/quack/types/time.rb', line 34

def ymd?(value)
  !!(value.to_s.strip =~ YMD_FORMAT)
end

Instance Method Details

#iso_8601?Boolean

Returns:



43
44
45
# File 'lib/quack/types/time.rb', line 43

def iso_8601?
  self.class.iso_8601?(value)
end

#parse_iso8601Object



55
56
57
58
59
60
61
62
# File 'lib/quack/types/time.rb', line 55

def parse_iso8601
  parts = value.to_s.scan(ISO_8601).flatten
  offset = parse_offset(parts.pop)
  parts = parts.map(&:to_i) << offset
  ::Time.new(*parts)
rescue => ex
  raise ParseError.new(ex.message)
end

#parse_offset(offset) ⇒ Object



51
52
53
# File 'lib/quack/types/time.rb', line 51

def parse_offset(offset)
  offset == "Z" ? UTC : offset
end

#parse_ymdObject



64
65
66
67
68
69
70
# File 'lib/quack/types/time.rb', line 64

def parse_ymd
  parts = value.to_s.scan(YMD_FORMAT).flatten
  parts = parts.map(&:to_i) + [0, 0, 0, UTC]
  ::Time.new(*parts)
rescue => ex
  raise ParseError.new(ex.message)
end

#to_coercedObject



72
73
74
75
76
# File 'lib/quack/types/time.rb', line 72

def to_coerced
  return value if already_coerced?
  return parse_iso8601 if iso_8601?
  parse_ymd
end

#to_sObject



78
79
80
# File 'lib/quack/types/time.rb', line 78

def to_s
  to_coerced.iso8601
end

#ymd?Boolean

Returns:



47
48
49
# File 'lib/quack/types/time.rb', line 47

def ymd?
  self.class.ymd?(value)
end