未验证 提交 420730b1 编写于 作者: A Alexey Shein 提交者: Jeremy Daer

Do not cache ActiveSupport::TimeZone#utc_offset

This can be an issue when TZInfo::TimeZone#current_period is refreshed
due to timezone period transition, but it's not reflected in
ActiveSupport::TimeZone object.

For example, on Sun, 26 Oct 2014 22:00 UTC, Moscow changed its TZ from
MSK +04:00 to MSK +03:00 (-1 hour). If ActiveSupport::TimeZone['Moscow']
happens to be initialized just before the timezone transition, it will
cache its stale utc_offset even after the timezone transition.

This commit removes cache and fixes this issue.
Signed-off-by: NJeremy Daer <jeremydaer@gmail.com>
上级 ea628f72
* Time zones: Ensure that the UTC offset reflects DST changes that occurred
since the app started. Removes UTC offset caching, reducing performance,
but this is still relatively quick and isn't in any hot paths.
*Alexey Shein*
* Make `getlocal` and `getutc` always return instances of `Time` for
`ActiveSupport::TimeWithZone` and `DateTime`. This eliminates a possible
stack level too deep error in `to_time` where `ActiveSupport::TimeWithZone`
......
......@@ -278,7 +278,6 @@ def initialize(name, utc_offset = nil, tzinfo = nil)
@name = name
@utc_offset = utc_offset
@tzinfo = tzinfo || TimeZone.find_tzinfo(name)
@current_period = nil
end
# Returns the offset of this time zone from UTC in seconds.
......@@ -286,8 +285,7 @@ def utc_offset
if @utc_offset
@utc_offset
else
@current_period ||= tzinfo.current_period if tzinfo
@current_period.utc_offset if @current_period
tzinfo.current_period.utc_offset if tzinfo && tzinfo.current_period
end
end
......
......@@ -395,6 +395,17 @@ def test_utc_offset_lazy_loaded_from_tzinfo_when_not_passed_in_to_initialize
assert_equal(-18_000, zone.utc_offset)
end
def test_utc_offset_is_not_cached_when_current_period_gets_stale
tz = ActiveSupport::TimeZone.create('Moscow')
travel_to(Time.utc(2014, 10, 25, 21)) do # 1 hour before TZ change
assert_equal 14400, tz.utc_offset, 'utc_offset should be initialized according to current_period'
end
travel_to(Time.utc(2014, 10, 25, 22)) do # after TZ change
assert_equal 10800, tz.utc_offset, 'utc_offset should not be cached when current_period gets stale'
end
end
def test_seconds_to_utc_offset_with_colon
assert_equal "-06:00", ActiveSupport::TimeZone.seconds_to_utc_offset(-21_600)
assert_equal "+00:00", ActiveSupport::TimeZone.seconds_to_utc_offset(0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册