Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zone_offset returns nil when it should return 0 for ISO8601 dates #24

Open
kongen84 opened this issue Jan 10, 2025 · 0 comments
Open

zone_offset returns nil when it should return 0 for ISO8601 dates #24

kongen84 opened this issue Jan 10, 2025 · 0 comments

Comments

@kongen84
Copy link

I get the error

NoMethodError: undefined method `<' for nil:NilClass

In time.rb:156 when I am parsing ISO8601-format (eg. 2024-10-17T12:49:41.854Z) expiration dates of cookies in a Rails 7 application.

The error comes from the apply_offset method being passed a nil value in the off parameter instead of a number. That value is calculated by the zone_offset method. Something goes wrong in the comparison with ZoneOffset but I don't understand why.

I've made a quick and dirty refinement, defining the zone offsets in a variable inside the method and this one works as expected.

module TimeRefinements
  refine Time do
    class << Time
      def zone_offset(zone, year=self.now.year)
        z_offset = {
          'UTC' => 0,
          # ISO 8601
          'Z' => 0,
          # RFC 822
          'UT' => 0, 'GMT' => 0,
          'EST' => -5, 'EDT' => -4,
          'CST' => -6, 'CDT' => -5,
          'MST' => -7, 'MDT' => -6,
          'PST' => -8, 'PDT' => -7,
          # Following definition of military zones is original one.
          # See RFC 1123 and RFC 2822 for the error in RFC 822.
          'A' => +1, 'B' => +2, 'C' => +3, 'D' => +4,  'E' => +5,  'F' => +6,
          'G' => +7, 'H' => +8, 'I' => +9, 'K' => +10, 'L' => +11, 'M' => +12,
          'N' => -1, 'O' => -2, 'P' => -3, 'Q' => -4,  'R' => -5,  'S' => -6,
          'T' => -7, 'U' => -8, 'V' => -9, 'W' => -10, 'X' => -11, 'Y' => -12,
        }

        off = nil
        zone = zone.upcase
        if /\A([+-])(\d\d)(:?)(\d\d)(?:\3(\d\d))?\z/ =~ zone
          off = ($1 == '-' ? -1 : 1) * (($2.to_i * 60 + $4.to_i) * 60 + $5.to_i)
        elsif zone.match?(/\A[+-]\d\d\z/)
          off = zone.to_i * 3600
        elsif z_offset.include?(zone)
          off = z_offset[zone] * 3600
        elsif ((t = self.local(year, 1, 1)).zone.upcase == zone rescue false)
          off = t.utc_offset
        elsif ((t = self.local(year, 7, 1)).zone.upcase == zone rescue false)
          off = t.utc_offset
        end
        off
      end
    end
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant