Class: ActiveSupport::Duration::ISO8601Parser

Inherits:
Object
  • Object
show all
Defined in:
activesupport/lib/active_support/duration/iso8601_parser.rb

Overview

Parses a string formatted according to ISO 8601 Duration into the hash.

See ISO 8601 for more information.

This parser allows negative parts to be present in pattern.

Defined Under Namespace

Classes: ParsingError

Constant Summary collapse

PERIOD_OR_COMMA =
/\.|,/
PERIOD =
"."
COMMA =
","
SIGN_MARKER =
/\A-|\+|/
DATE_MARKER =
/P/
TIME_MARKER =
/T/
DATE_COMPONENT =
/(-?\d+(?:[.,]\d+)?)(Y|M|D|W)/
TIME_COMPONENT =
/(-?\d+(?:[.,]\d+)?)(H|M|S)/
DATE_TO_PART =
{ "Y" => :years, "M" => :months, "W" => :weeks, "D" => :days }
TIME_TO_PART =
{ "H" => :hours, "M" => :minutes, "S" => :seconds }
DATE_COMPONENTS =
[:years, :months, :days]
TIME_COMPONENTS =
[:hours, :minutes, :seconds]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(string) ⇒ ISO8601Parser

Returns a new instance of ISO8601Parser.

[View source]

34
35
36
37
38
39
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 34

def initialize(string)
  @scanner = StringScanner.new(string)
  @parts = {}
  @mode = :start
  @sign = 1
end

Instance Attribute Details

#modeObject

Returns the value of attribute mode.


32
33
34
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 32

def mode
  @mode
end

#partsObject (readonly)

Returns the value of attribute parts.


31
32
33
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 31

def parts
  @parts
end

#scannerObject (readonly)

Returns the value of attribute scanner.


31
32
33
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 31

def scanner
  @scanner
end

#signObject

Returns the value of attribute sign.


32
33
34
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 32

def sign
  @sign
end

Instance Method Details

#parse!Object

[View source]

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 41

def parse!
  while !finished?
    case mode
    when :start
      if scan(SIGN_MARKER)
        self.sign = (scanner.matched == "-") ? -1 : 1
        self.mode = :sign
      else
        raise_parsing_error
      end

    when :sign
      if scan(DATE_MARKER)
        self.mode = :date
      else
        raise_parsing_error
      end

    when :date
      if scan(TIME_MARKER)
        self.mode = :time
      elsif scan(DATE_COMPONENT)
        parts[DATE_TO_PART[scanner[2]]] = number * sign
      else
        raise_parsing_error
      end

    when :time
      if scan(TIME_COMPONENT)
        parts[TIME_TO_PART[scanner[2]]] = number * sign
      else
        raise_parsing_error
      end

    end
  end

  validate!
  parts
end