diff options
author | Andrew White <andrew.white@unboxed.co> | 2016-10-31 17:21:15 +0000 |
---|---|---|
committer | Andrew White <andrew.white@unboxed.co> | 2016-10-31 17:25:43 +0000 |
commit | 8931916f4a1c1d8e70c06063ba63928c5c7eab1e (patch) | |
tree | 936a2edb3fcacb16cc7357309b682781d1ce4f9e /activesupport/test | |
parent | 3c9eb704e8b7fc175728f0340043b888120764cc (diff) | |
download | rails-8931916f4a1c1d8e70c06063ba63928c5c7eab1e.tar.gz rails-8931916f4a1c1d8e70c06063ba63928c5c7eab1e.tar.bz2 rails-8931916f4a1c1d8e70c06063ba63928c5c7eab1e.zip |
Ensure duration parsing is consistent across DST changes
Previously `ActiveSupport::Duration.parse` used `Time.current` and
`Time#advance` to calculate the number of seconds in the duration
from an arbitrary collection of parts. However as `advance` tries to
be consistent across DST boundaries this meant that either the
duration was shorter or longer depending on the time of year.
This was fixed by using an absolute reference point in UTC which
isn't subject to DST transitions. An arbitrary date of Jan 1st, 2000
was chosen for no other reason that it seemed appropriate.
Additionally, duration parsing should now be marginally faster as we
are no longer creating instances of `ActiveSupport::TimeWithZone`
every time we parse a duration string.
Fixes #26941.
Diffstat (limited to 'activesupport/test')
-rw-r--r-- | activesupport/test/core_ext/duration_test.rb | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb index 53575272e3..c8e8b8a350 100644 --- a/activesupport/test/core_ext/duration_test.rb +++ b/activesupport/test/core_ext/duration_test.rb @@ -322,4 +322,35 @@ class DurationTest < ActiveSupport::TestCase assert_equal time + duration, time + ActiveSupport::Duration.parse(duration.iso8601), pattern.inspect end end + + def test_iso8601_parsing_across_spring_dst_boundary + with_env_tz eastern_time_zone do + with_tz_default "Eastern Time (US & Canada)" do + travel_to Time.utc(2016, 3, 11) do + assert_equal 604800, ActiveSupport::Duration.parse("P7D").to_i + assert_equal 604800, ActiveSupport::Duration.parse("P1W").to_i + end + end + end + end + + def test_iso8601_parsing_across_autumn_dst_boundary + with_env_tz eastern_time_zone do + with_tz_default "Eastern Time (US & Canada)" do + travel_to Time.utc(2016, 11, 4) do + assert_equal 604800, ActiveSupport::Duration.parse("P7D").to_i + assert_equal 604800, ActiveSupport::Duration.parse("P1W").to_i + end + end + end + end + + private + def eastern_time_zone + if Gem.win_platform? + "EST5EDT" + else + "America/New_York" + end + end end |