rails: ActiveSupport::JSON.decode Fails Decoding ISO8601 Date/Time String

When using activesupport to parse JSON a seemingly valid datetime string (``“2015-02-14T02:21:34”`) seems to not get parsed into a valid datetime.

Full example:

$ rails c
Loading development environment (Rails 4.2.4)
2.2.3 :001 > ActiveSupport.parse_json_times = True
2.2.3 :002 > ActiveSupport::JSON.decode('{"a":"2015-02-14T02:21:34"}')
 => {"a"=>"2015-02-14T02:21:34"}  # Incorrectly a string

2.2.3 :003 > ActiveSupport::JSON.decode('{"a":"2015-02-14T02:21:34Z"}')
 => {"a"=>Sat, 14 Feb 2015 02:21:34 +0000}  # Correctly a datetime

I believe the string "2015-02-14T02:21:34" is a valid iso8601 datetime string (it just doesn’t have a timezone indicator).

If you trace the source of this it goes to activesupport/lib/activesupport/decoding.rb and the regular expression

DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/

Should probably be

DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)$/

Note the ? as the 4rd to last character in the expression

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 17 (15 by maintainers)

Commits related to this issue

Most upvoted comments

The standards are fairly unclear on this - ISO8601 (according to Wikipedia, anyways) specifies that datetimes without a TZ indicator are to be regarded as “local” time. Note that fixing the regex as described above DOES NOT fix this; DateTime.parse believes strings without TZ information to be in UTC.

RFC3339, on the other hand, explicitly requires either the T+offset form or the Z.