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)
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 theZ
.