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

Adjust for daylight savings in String#to_time

The changes in b79adc4323 had a bug where if the time in the String
was in standard time but the current time was in daylight savings then
the calculated adjustment was off by an hour.

This commit fixes this and adds extra tests for the following:

* time in string is standard time, current time is standard time
* time in string is standard time, current time is daylight savings
* time in string is daylight savings, current time is standard time
* time in string is daylight savings, current time is daylight savings

Fixes #10306.
This commit is contained in:
Andrew White 2013-04-23 12:48:31 +01:00
parent 756cba02c1
commit a56b150b64
2 changed files with 124 additions and 10 deletions

View file

@ -20,19 +20,17 @@ class String
return if parts.empty?
now = Time.now
offset = parts[:offset]
utc_offset = form == :utc ? 0 : now.utc_offset
adjustment = offset ? offset - utc_offset : 0
Time.send(
form,
time = Time.new(
parts.fetch(:year, now.year),
parts.fetch(:mon, now.month),
parts.fetch(:mday, now.day),
parts.fetch(:hour, 0),
parts.fetch(:min, 0),
parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0)
) - adjustment
parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
parts.fetch(:offset, form == :utc ? 0 : nil)
)
form == :utc ? time.utc : time.getlocal
end
# Converts a string to a Date value.

View file

@ -300,9 +300,9 @@ class StringConversionsTest < ActiveSupport::TestCase
assert_equal Time.local(2005, 2, 27, 23, 50, 19, 275038), "2005-02-27T23:50:19.275038".to_time
assert_equal Time.utc(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time(:utc)
assert_equal Time.local(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time
assert_equal Time.local(2011, 2, 27, 18, 50), "2011-02-27 13:50 -0100".to_time
assert_equal Time.local(2011, 2, 27, 17, 50), "2011-02-27 13:50 -0100".to_time
assert_equal Time.utc(2011, 2, 27, 23, 50), "2011-02-27 22:50 -0100".to_time(:utc)
assert_equal Time.local(2005, 2, 27, 23, 50), "2005-02-27 14:50 -0500".to_time
assert_equal Time.local(2005, 2, 27, 22, 50), "2005-02-27 14:50 -0500".to_time
assert_nil "".to_time
end
end
@ -326,6 +326,122 @@ class StringConversionsTest < ActiveSupport::TestCase
end
end
def test_standard_time_string_to_time_when_current_time_is_standard_time
with_env_tz "US/Eastern" do
Time.stubs(:now).returns(Time.local(2012, 1, 1))
assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time
assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 -0800".to_time
assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 -0800".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 -0500".to_time
assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 -0500".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 5, 0), "2012-01-01 10:00 UTC".to_time
assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00 UTC".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 PST".to_time
assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 PST".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 EST".to_time
assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 EST".to_time(:utc)
end
end
def test_standard_time_string_to_time_when_current_time_is_daylight_savings
with_env_tz "US/Eastern" do
Time.stubs(:now).returns(Time.local(2012, 7, 1))
assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time
assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 -0800".to_time
assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 -0800".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 -0500".to_time
assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 -0500".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 5, 0), "2012-01-01 10:00 UTC".to_time
assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00 UTC".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 PST".to_time
assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 PST".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 EST".to_time
assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 EST".to_time(:utc)
end
end
def test_daylight_savings_string_to_time_when_current_time_is_standard_time
with_env_tz "US/Eastern" do
Time.stubs(:now).returns(Time.local(2012, 1, 1))
assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time
assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 -0700".to_time
assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 -0700".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 -0400".to_time
assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 -0400".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 6, 0), "2012-07-01 10:00 UTC".to_time
assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00 UTC".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 PDT".to_time
assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 PDT".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 EDT".to_time
assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 EDT".to_time(:utc)
end
end
def test_daylight_savings_string_to_time_when_current_time_is_daylight_savings
with_env_tz "US/Eastern" do
Time.stubs(:now).returns(Time.local(2012, 7, 1))
assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time
assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 -0700".to_time
assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 -0700".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 -0400".to_time
assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 -0400".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 6, 0), "2012-07-01 10:00 UTC".to_time
assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00 UTC".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 PDT".to_time
assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 PDT".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 EDT".to_time
assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 EDT".to_time(:utc)
end
end
def test_partial_string_to_time_when_current_time_is_standard_time
with_env_tz "US/Eastern" do
Time.stubs(:now).returns(Time.local(2012, 1, 1))
assert_equal Time.local(2012, 1, 1, 10, 0), "10:00".to_time
assert_equal Time.utc(2012, 1, 1, 10, 0), "10:00".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 6, 0), "10:00 -0100".to_time
assert_equal Time.utc(2012, 1, 1, 11, 0), "10:00 -0100".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 10, 0), "10:00 -0500".to_time
assert_equal Time.utc(2012, 1, 1, 15, 0), "10:00 -0500".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 5, 0), "10:00 UTC".to_time
assert_equal Time.utc(2012, 1, 1, 10, 0), "10:00 UTC".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 13, 0), "10:00 PST".to_time
assert_equal Time.utc(2012, 1, 1, 18, 0), "10:00 PST".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 12, 0), "10:00 PDT".to_time
assert_equal Time.utc(2012, 1, 1, 17, 0), "10:00 PDT".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 10, 0), "10:00 EST".to_time
assert_equal Time.utc(2012, 1, 1, 15, 0), "10:00 EST".to_time(:utc)
assert_equal Time.local(2012, 1, 1, 9, 0), "10:00 EDT".to_time
assert_equal Time.utc(2012, 1, 1, 14, 0), "10:00 EDT".to_time(:utc)
end
end
def test_partial_string_to_time_when_current_time_is_daylight_savings
with_env_tz "US/Eastern" do
Time.stubs(:now).returns(Time.local(2012, 7, 1))
assert_equal Time.local(2012, 7, 1, 10, 0), "10:00".to_time
assert_equal Time.utc(2012, 7, 1, 10, 0), "10:00".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 7, 0), "10:00 -0100".to_time
assert_equal Time.utc(2012, 7, 1, 11, 0), "10:00 -0100".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 11, 0), "10:00 -0500".to_time
assert_equal Time.utc(2012, 7, 1, 15, 0), "10:00 -0500".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 6, 0), "10:00 UTC".to_time
assert_equal Time.utc(2012, 7, 1, 10, 0), "10:00 UTC".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 14, 0), "10:00 PST".to_time
assert_equal Time.utc(2012, 7, 1, 18, 0), "10:00 PST".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 13, 0), "10:00 PDT".to_time
assert_equal Time.utc(2012, 7, 1, 17, 0), "10:00 PDT".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 11, 0), "10:00 EST".to_time
assert_equal Time.utc(2012, 7, 1, 15, 0), "10:00 EST".to_time(:utc)
assert_equal Time.local(2012, 7, 1, 10, 0), "10:00 EDT".to_time
assert_equal Time.utc(2012, 7, 1, 14, 0), "10:00 EDT".to_time(:utc)
end
end
def test_string_to_datetime
assert_equal DateTime.civil(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_datetime
assert_equal 0, "2039-02-27 23:50".to_datetime.offset # use UTC offset