mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Handle TZInfo::AmbiguousTime
errors
Make `ActiveSupport::TimeWithZone` match Ruby's handling of ambiguous times by choosing the later period, e.g. Ruby: ``` ENV["TZ"] = "Europe/Moscow" Time.local(2014, 10, 26, 1, 0, 0) # => 2014-10-26 01:00:00 +0300 ``` Before: ``` >> "2014-10-26 01:00:00".in_time_zone("Moscow") TZInfo::AmbiguousTime: 26/10/2014 01:00 is an ambiguous local time. ``` After: ``` >> "2014-10-26 01:00:00".in_time_zone("Moscow") => Sun, 26 Oct 2014 01:00:00 MSK +03:00 ``` Fixes #17395.
This commit is contained in:
parent
23c41e4657
commit
2eea6458a1
4 changed files with 66 additions and 1 deletions
|
@ -1,3 +1,30 @@
|
|||
* Handle `TZInfo::AmbiguousTime` errors
|
||||
|
||||
Make `ActiveSupport::TimeWithZone` match Ruby's handling of ambiguous
|
||||
times by choosing the later period, e.g.
|
||||
|
||||
Ruby:
|
||||
```
|
||||
ENV["TZ"] = "Europe/Moscow"
|
||||
Time.local(2014, 10, 26, 1, 0, 0) # => 2014-10-26 01:00:00 +0300
|
||||
```
|
||||
|
||||
Before:
|
||||
```
|
||||
>> "2014-10-26 01:00:00".in_time_zone("Moscow")
|
||||
TZInfo::AmbiguousTime: 26/10/2014 01:00 is an ambiguous local time.
|
||||
```
|
||||
|
||||
After:
|
||||
```
|
||||
>> "2014-10-26 01:00:00".in_time_zone("Moscow")
|
||||
=> Sun, 26 Oct 2014 01:00:00 MSK +03:00
|
||||
```
|
||||
|
||||
Fixes #17395.
|
||||
|
||||
*Andrew White*
|
||||
|
||||
* Redis cache store.
|
||||
|
||||
```
|
||||
|
|
|
@ -506,7 +506,7 @@ module ActiveSupport
|
|||
# Available so that TimeZone instances respond like TZInfo::Timezone
|
||||
# instances.
|
||||
def period_for_local(time, dst = true)
|
||||
tzinfo.period_for_local(time, dst)
|
||||
tzinfo.period_for_local(time, dst) { |periods| periods.last }
|
||||
end
|
||||
|
||||
def periods_for_local(time) #:nodoc:
|
||||
|
|
|
@ -50,6 +50,12 @@ class TimeWithZoneTest < ActiveSupport::TestCase
|
|||
assert_raise(ArgumentError) { @twz.in_time_zone(Object.new) }
|
||||
end
|
||||
|
||||
def test_in_time_zone_with_ambiguous_time
|
||||
with_env_tz "Europe/Moscow" do
|
||||
assert_equal Time.utc(2014, 10, 25, 22, 0, 0), Time.local(2014, 10, 26, 1, 0, 0).in_time_zone("Moscow")
|
||||
end
|
||||
end
|
||||
|
||||
def test_localtime
|
||||
assert_equal @twz.localtime, @twz.utc.getlocal
|
||||
assert_instance_of Time, @twz.localtime
|
||||
|
@ -1301,4 +1307,10 @@ class TimeWithZoneMethodsForString < ActiveSupport::TestCase
|
|||
assert_raise(ArgumentError) { @u.in_time_zone(Object.new) }
|
||||
assert_raise(ArgumentError) { @z.in_time_zone(Object.new) }
|
||||
end
|
||||
|
||||
def test_in_time_zone_with_ambiguous_time
|
||||
with_tz_default "Moscow" do
|
||||
assert_equal Time.utc(2014, 10, 25, 22, 0, 0), "2014-10-26 01:00:00".in_time_zone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,6 +32,12 @@ class TimeZoneTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_period_for_local_with_ambigiuous_time
|
||||
zone = ActiveSupport::TimeZone["Moscow"]
|
||||
period = zone.period_for_local(Time.utc(2015, 1, 1))
|
||||
assert_equal period, zone.period_for_local(Time.utc(2014, 10, 26, 1, 0, 0))
|
||||
end
|
||||
|
||||
def test_from_integer_to_map
|
||||
assert_instance_of ActiveSupport::TimeZone, ActiveSupport::TimeZone[-28800] # PST
|
||||
end
|
||||
|
@ -195,6 +201,11 @@ class TimeZoneTest < ActiveSupport::TestCase
|
|||
assert_equal "EDT", twz.zone
|
||||
end
|
||||
|
||||
def test_local_with_ambiguous_time
|
||||
zone = ActiveSupport::TimeZone["Moscow"]
|
||||
assert_equal Time.utc(2014, 10, 25, 22, 0, 0), zone.local(2014, 10, 26, 1, 0, 0)
|
||||
end
|
||||
|
||||
def test_at
|
||||
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||
secs = 946684800.0
|
||||
|
@ -303,6 +314,11 @@ class TimeZoneTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_iso8601_with_ambiguous_time
|
||||
zone = ActiveSupport::TimeZone["Moscow"]
|
||||
assert_equal Time.utc(2014, 10, 25, 22, 0, 0), zone.parse("2014-10-26T01:00:00")
|
||||
end
|
||||
|
||||
def test_parse
|
||||
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||
twz = zone.parse("1999-12-31 19:00:00")
|
||||
|
@ -412,6 +428,11 @@ class TimeZoneTest < ActiveSupport::TestCase
|
|||
assert_equal "argument out of range", exception.message
|
||||
end
|
||||
|
||||
def test_parse_with_ambiguous_time
|
||||
zone = ActiveSupport::TimeZone["Moscow"]
|
||||
assert_equal Time.utc(2014, 10, 25, 22, 0, 0), zone.parse("2014-10-26 01:00:00")
|
||||
end
|
||||
|
||||
def test_rfc3339
|
||||
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||
twz = zone.rfc3339("1999-12-31T14:00:00-10:00")
|
||||
|
@ -604,6 +625,11 @@ class TimeZoneTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_strptime_with_ambiguous_time
|
||||
zone = ActiveSupport::TimeZone["Moscow"]
|
||||
assert_equal Time.utc(2014, 10, 25, 22, 0, 0), zone.strptime("2014-10-26 01:00:00", "%Y-%m-%d %H:%M:%S")
|
||||
end
|
||||
|
||||
def test_utc_offset_lazy_loaded_from_tzinfo_when_not_passed_in_to_initialize
|
||||
tzinfo = TZInfo::Timezone.get("America/New_York")
|
||||
zone = ActiveSupport::TimeZone.create(tzinfo.name, nil, tzinfo)
|
||||
|
|
Loading…
Reference in a new issue