提交 a3ddd5f1 编写于 作者: G Grzegorz Witek

Use correct timezone when parsing date in json

Fixes https://github.com/rails/rails/issues/22171

Time specified in ISO 8601 format without `Z` should be considered as local
time, yet until now it was treated as UTC.

This commit fixes problem by parsing time using timezone specified in
application config.

The downside of this solution is performance hit (`Time.zone.parse` is ~ 1.6x
slower than `Time.parse`), so maybe there's a better solution.
上级 9a99c7ce
* Fix parsing JSON time in `YYYY-MM-DD hh:mm:ss` (without `Z`).
Before such time was considered in UTC timezone, now, to comply with standard, it uses local timezone.
*Grzegorz Witek*
* Match `HashWithIndifferentAccess#default`'s behaviour with `Hash#default`.
*David Cornu*
......
......@@ -8,7 +8,8 @@ module ActiveSupport
module JSON
# matches YAML-formatted dates
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})?))$/
DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/
DATETIME_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})?)?)$/
class << self
# Parses a JSON string (JavaScript Object Notation) into a hash.
......@@ -48,7 +49,13 @@ def convert_dates_from(data)
nil
when DATE_REGEX
begin
DateTime.parse(data)
Date.parse(data)
rescue ArgumentError
data
end
when DATETIME_REGEX
begin
Time.zone.parse(data)
rescue ArgumentError
data
end
......
require 'abstract_unit'
require 'active_support/json'
require 'active_support/time'
require 'time_zone_test_helpers'
class TestJSONDecoding < ActiveSupport::TestCase
include TimeZoneTestHelpers
class Foo
def self.json_create(object)
"Foo"
......@@ -24,10 +27,11 @@ def self.json_create(object)
%(["2007-01-01 01:12:34 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34)],
%(["2007-01-01 01:12:34 Z", "2007-01-01 01:12:35 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34), Time.utc(2007, 1, 1, 1, 12, 35)],
# no time zone
%({"a": "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
%({"a": "2007-01-01 01:12:34"}) => {'a' => Time.new(2007, 1, 1, 1, 12, 34, "-05:00")},
# invalid date
%({"a": "1089-10-40"}) => {'a' => "1089-10-40"},
# xmlschema date notation
%({"a": "2009-08-10T19:01:02"}) => {'a' => Time.new(2009, 8, 10, 19, 1, 2, "-04:00")},
%({"a": "2009-08-10T19:01:02Z"}) => {'a' => Time.utc(2009, 8, 10, 19, 1, 2)},
%({"a": "2009-08-10T19:01:02+02:00"}) => {'a' => Time.utc(2009, 8, 10, 17, 1, 2)},
%({"a": "2009-08-10T19:01:02-05:00"}) => {'a' => Time.utc(2009, 8, 11, 00, 1, 2)},
......@@ -72,10 +76,12 @@ def self.json_create(object)
TESTS.each_with_index do |(json, expected), index|
test "json decodes #{index}" do
with_parse_json_times(true) do
silence_warnings do
assert_equal expected, ActiveSupport::JSON.decode(json), "JSON decoding \
failed for #{json}"
with_tz_default 'Eastern Time (US & Canada)' do
with_parse_json_times(true) do
silence_warnings do
assert_equal expected, ActiveSupport::JSON.decode(json), "JSON decoding \
failed for #{json}"
end
end
end
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册