1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #41929 from rails/fix-utc-to-local-with-fractional-seconds

Fix ActiveSupport::TimeZone#utc_to_local with fractional seconds
This commit is contained in:
Andrew White 2021-04-13 09:21:09 +01:00 committed by GitHub
commit 3145c588af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 1 deletions

View file

@ -1,3 +1,12 @@
* Fix `ActiveSupport::TimeZone#utc_to_local` with fractional seconds.
When `utc_to_local_returns_utc_offset_times` is false and the time
instance had fractional seconds the new UTC time instance was out by
a factor of 1,000,000 as the `Time.utc` constructor takes a usec
value and not a fractional second value.
*Andrew White*
* Fix issue in `Hash#deep_merge` where it did not properly duplicate a nested `Hash` * Fix issue in `Hash#deep_merge` where it did not properly duplicate a nested `Hash`
*Marcel Eeken* *Marcel Eeken*

View file

@ -513,7 +513,7 @@ module ActiveSupport
def utc_to_local(time) def utc_to_local(time)
tzinfo.utc_to_local(time).yield_self do |t| tzinfo.utc_to_local(time).yield_self do |t|
ActiveSupport.utc_to_local_returns_utc_offset_times ? ActiveSupport.utc_to_local_returns_utc_offset_times ?
t : Time.utc(t.year, t.month, t.day, t.hour, t.min, t.sec, t.sec_fraction) t : Time.utc(t.year, t.month, t.day, t.hour, t.min, t.sec, t.sec_fraction * 1_000_000)
end end
end end

View file

@ -15,12 +15,28 @@ class TimeZoneTest < ActiveSupport::TestCase
assert_equal Time.utc(1999, 12, 31, 19), zone.utc_to_local(Time.utc(2000, 1)) # standard offset -0500 assert_equal Time.utc(1999, 12, 31, 19), zone.utc_to_local(Time.utc(2000, 1)) # standard offset -0500
assert_equal Time.utc(2000, 6, 30, 20), zone.utc_to_local(Time.utc(2000, 7)) # dst offset -0400 assert_equal Time.utc(2000, 6, 30, 20), zone.utc_to_local(Time.utc(2000, 7)) # dst offset -0400
end end
with_utc_to_local_returns_utc_offset_times true do with_utc_to_local_returns_utc_offset_times true do
assert_equal Time.new(1999, 12, 31, 19, 0, 0, -18000), zone.utc_to_local(Time.utc(2000, 1)) # standard offset -0500 assert_equal Time.new(1999, 12, 31, 19, 0, 0, -18000), zone.utc_to_local(Time.utc(2000, 1)) # standard offset -0500
assert_equal Time.new(2000, 6, 30, 20, 0, 0, -14400), zone.utc_to_local(Time.utc(2000, 7)) # dst offset -0400 assert_equal Time.new(2000, 6, 30, 20, 0, 0, -14400), zone.utc_to_local(Time.utc(2000, 7)) # dst offset -0400
end end
end end
def test_utc_to_local_with_fractional_seconds
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
usec = Rational(1, 1000000)
with_utc_to_local_returns_utc_offset_times false do
assert_equal Time.utc(1999, 12, 31, 19, 0, 0, 1), zone.utc_to_local(Time.utc(2000, 1, 1, 0, 0, 0, 1)) # standard offset -0500
assert_equal Time.utc(2000, 6, 30, 20, 0, 0, 1), zone.utc_to_local(Time.utc(2000, 7, 1, 0, 0, 0, 1)) # dst offset -0400
end
with_utc_to_local_returns_utc_offset_times true do
assert_equal Time.new(1999, 12, 31, 19, 0, usec, -18000), zone.utc_to_local(Time.utc(2000, 1, 1, 0, 0, 0, 1)) # standard offset -0500
assert_equal Time.new(2000, 6, 30, 20, 0, usec, -14400), zone.utc_to_local(Time.utc(2000, 7, 1, 0, 0, 0, 1)) # dst offset -0400
end
end
def test_local_to_utc def test_local_to_utc
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"] zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
assert_equal Time.utc(2000, 1, 1, 5), zone.local_to_utc(Time.utc(2000, 1)) # standard offset -0500 assert_equal Time.utc(2000, 1, 1, 5), zone.local_to_utc(Time.utc(2000, 1)) # standard offset -0500