From 8ea857b15018f0b0b4046cecf20aa160748b51b7 Mon Sep 17 00:00:00 2001 From: Michael Curtis Date: Tue, 10 Mar 2009 12:14:54 -0500 Subject: [PATCH] Adding 24.hours across the DST boundary should add 24 hours instead of one day. --- .../active_support/core_ext/time/calculations.rb | 14 ++------- activesupport/test/core_ext/duration_test.rb | 12 +++++++ activesupport/test/core_ext/time_ext_test.rb | 32 ++++++++++---------- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 5ed750a..d13d0e0 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -116,22 +116,14 @@ module ActiveSupport #:nodoc: seconds_to_advance == 0 ? time_advanced_by_date : time_advanced_by_date.since(seconds_to_advance) end - # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension + # Returns a new Time representing the time a number of seconds ago def ago(seconds) self.since(-seconds) end - # Returns a new Time representing the time a number of seconds since the instance time, this is basically a wrapper around - # the Numeric extension. + # Returns a new Time representing the time a number of seconds since the instance time def since(seconds) - f = seconds.since(self) - if ActiveSupport::Duration === seconds - f - else - initial_dst = self.dst? ? 1 : 0 - final_dst = f.dst? ? 1 : 0 - (seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f - end + self + seconds rescue self.to_datetime.since(seconds) end diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb index ab5a866..8954295 100644 --- a/activesupport/test/core_ext/duration_test.rb +++ b/activesupport/test/core_ext/duration_test.rb @@ -109,6 +109,18 @@ class DurationTest < ActiveSupport::TestCase ensure Time.zone_default = nil end + + def test_adding_hours_across_dst_boundary + with_env_tz 'CET' do + assert_equal Time.local(2009,3,29,0,0,0) + 24.hours, Time.local(2009,3,30,1,0,0) + end + end + + def test_adding_day_across_dst_boundary + with_env_tz 'CET' do + assert_equal Time.local(2009,3,29,0,0,0) + 1.day, Time.local(2009,3,30,0,0,0) + end + end protected def with_env_tz(new_tz = 'US/Eastern') diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index c085552..1775f81 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -183,26 +183,26 @@ class TimeExtCalculationsTest < Test::Unit::TestCase def test_daylight_savings_time_crossings_backward_start with_env_tz 'US/Eastern' do # dt: US: 2005 April 3rd 4:18am - assert_equal Time.local(2005,4,2,4,18,0), Time.local(2005,4,3,4,18,0).ago(86400), 'dt-1.day=>st' - assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(86400), 'st-1.day=>st' + assert_equal Time.local(2005,4,2,3,18,0), Time.local(2005,4,3,4,18,0).ago(24.hours), 'dt-1.day=>st' + assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(24.hours), 'st-1.day=>st' end with_env_tz 'NZ' do # dt: New Zealand: 2006 October 1st 4:18am - assert_equal Time.local(2006,9,30,4,18,0), Time.local(2006,10,1,4,18,0).ago(86400), 'dt-1.day=>st' - assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(86400), 'st-1.day=>st' + assert_equal Time.local(2006,9,30,3,18,0), Time.local(2006,10,1,4,18,0).ago(24.hours), 'dt-1.day=>st' + assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(24.hours), 'st-1.day=>st' end end def test_daylight_savings_time_crossings_backward_end with_env_tz 'US/Eastern' do # st: US: 2005 October 30th 4:03am - assert_equal Time.local(2005,10,29,4,3), Time.local(2005,10,30,4,3,0).ago(86400), 'st-1.day=>dt' - assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(86400), 'dt-1.day=>dt' + assert_equal Time.local(2005,10,29,5,3), Time.local(2005,10,30,4,3,0).ago(24.hours), 'st-1.day=>dt' + assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(24.hours), 'dt-1.day=>dt' end with_env_tz 'NZ' do # st: New Zealand: 2006 March 19th 4:03am - assert_equal Time.local(2006,3,18,4,3), Time.local(2006,3,19,4,3,0).ago(86400), 'st-1.day=>dt' - assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(86400), 'dt-1.day=>dt' + assert_equal Time.local(2006,3,18,5,3), Time.local(2006,3,19,4,3,0).ago(24.hours), 'st-1.day=>dt' + assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(24.hours), 'dt-1.day=>dt' end end @@ -243,13 +243,13 @@ class TimeExtCalculationsTest < Test::Unit::TestCase def test_daylight_savings_time_crossings_forward_start with_env_tz 'US/Eastern' do # st: US: 2005 April 2nd 7:27pm - assert_equal Time.local(2005,4,3,19,27,0), Time.local(2005,4,2,19,27,0).since(86400), 'st+1.day=>dt' - assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(86400), 'dt+1.day=>dt' + assert_equal Time.local(2005,4,3,20,27,0), Time.local(2005,4,2,19,27,0).since(24.hours), 'st+1.day=>dt' + assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(24.hours), 'dt+1.day=>dt' end with_env_tz 'NZ' do # st: New Zealand: 2006 September 30th 7:27pm - assert_equal Time.local(2006,10,1,19,27,0), Time.local(2006,9,30,19,27,0).since(86400), 'st+1.day=>dt' - assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(86400), 'dt+1.day=>dt' + assert_equal Time.local(2006,10,1,20,27,0), Time.local(2006,9,30,19,27,0).since(24.hours), 'st+1.day=>dt' + assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(24.hours), 'dt+1.day=>dt' end end @@ -295,13 +295,13 @@ class TimeExtCalculationsTest < Test::Unit::TestCase def test_daylight_savings_time_crossings_forward_end with_env_tz 'US/Eastern' do # dt: US: 2005 October 30th 12:45am - assert_equal Time.local(2005,10,31,0,45,0), Time.local(2005,10,30,0,45,0).since(86400), 'dt+1.day=>st' - assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(86400), 'st+1.day=>st' + assert_equal Time.local(2005,10,30,23,45,0), Time.local(2005,10,30,0,45,0).since(24.hours), 'dt+1.day=>st' + assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(24.hours), 'st+1.day=>st' end with_env_tz 'NZ' do # dt: New Zealand: 2006 March 19th 1:45am - assert_equal Time.local(2006,3,20,1,45,0), Time.local(2006,3,19,1,45,0).since(86400), 'dt+1.day=>st' - assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(86400), 'st+1.day=>st' + assert_equal Time.local(2006,3,20,0,45,0), Time.local(2006,3,19,1,45,0).since(24.hours), 'dt+1.day=>st' + assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(24.hours), 'st+1.day=>st' end end -- 1.6.1.3