Skip to content

Commit 5a8b481

Browse files
mcurtisgbuesing
authored andcommitted
Time.local instances: Adding 24.hours across the DST boundary adds 24 hours instead of one day [rails#2066 state:resolved]
1 parent dd2eb1e commit 5a8b481

File tree

4 files changed

+36
-27
lines changed

4 files changed

+36
-27
lines changed

activesupport/CHANGELOG

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
*Edge
2+
3+
* Time.local instances: Adding 24.hours across the DST boundary adds 24 hours instead of one day #2066 [Michael Curtis]
4+
5+
16
*2.3.2 [Final] (March 15, 2009)*
27

38
* XmlMini supports LibXML and Nokogiri backends. #2084, #2190 [Bart ten Brinke, Aaron Patterson]

activesupport/lib/active_support/core_ext/time/calculations.rb

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,22 +116,14 @@ def advance(options)
116116
seconds_to_advance == 0 ? time_advanced_by_date : time_advanced_by_date.since(seconds_to_advance)
117117
end
118118

119-
# Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension
119+
# Returns a new Time representing the time a number of seconds ago
120120
def ago(seconds)
121121
self.since(-seconds)
122122
end
123123

124-
# Returns a new Time representing the time a number of seconds since the instance time, this is basically a wrapper around
125-
# the Numeric extension.
124+
# Returns a new Time representing the time a number of seconds since the instance time
126125
def since(seconds)
127-
f = seconds.since(self)
128-
if ActiveSupport::Duration === seconds
129-
f
130-
else
131-
initial_dst = self.dst? ? 1 : 0
132-
final_dst = f.dst? ? 1 : 0
133-
(seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f
134-
end
126+
self + seconds
135127
rescue
136128
self.to_datetime.since(seconds)
137129
end

activesupport/test/core_ext/duration_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ def test_since_and_ago_anchored_to_time_zone_now_when_time_zone_default_set
109109
ensure
110110
Time.zone_default = nil
111111
end
112+
113+
def test_adding_hours_across_dst_boundary
114+
with_env_tz 'CET' do
115+
assert_equal Time.local(2009,3,29,0,0,0) + 24.hours, Time.local(2009,3,30,1,0,0)
116+
end
117+
end
118+
119+
def test_adding_day_across_dst_boundary
120+
with_env_tz 'CET' do
121+
assert_equal Time.local(2009,3,29,0,0,0) + 1.day, Time.local(2009,3,30,0,0,0)
122+
end
123+
end
112124

113125
protected
114126
def with_env_tz(new_tz = 'US/Eastern')

activesupport/test/core_ext/time_ext_test.rb

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -183,26 +183,26 @@ def test_ago
183183
def test_daylight_savings_time_crossings_backward_start
184184
with_env_tz 'US/Eastern' do
185185
# dt: US: 2005 April 3rd 4:18am
186-
assert_equal Time.local(2005,4,2,4,18,0), Time.local(2005,4,3,4,18,0).ago(86400), 'dt-1.day=>st'
187-
assert_equal Time.local(2005,4,1,4,18,0), Time.local(2005,4,2,4,18,0).ago(86400), 'st-1.day=>st'
186+
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'
187+
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'
188188
end
189189
with_env_tz 'NZ' do
190190
# dt: New Zealand: 2006 October 1st 4:18am
191-
assert_equal Time.local(2006,9,30,4,18,0), Time.local(2006,10,1,4,18,0).ago(86400), 'dt-1.day=>st'
192-
assert_equal Time.local(2006,9,29,4,18,0), Time.local(2006,9,30,4,18,0).ago(86400), 'st-1.day=>st'
191+
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'
192+
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'
193193
end
194194
end
195195

196196
def test_daylight_savings_time_crossings_backward_end
197197
with_env_tz 'US/Eastern' do
198198
# st: US: 2005 October 30th 4:03am
199-
assert_equal Time.local(2005,10,29,4,3), Time.local(2005,10,30,4,3,0).ago(86400), 'st-1.day=>dt'
200-
assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(86400), 'dt-1.day=>dt'
199+
assert_equal Time.local(2005,10,29,5,3), Time.local(2005,10,30,4,3,0).ago(24.hours), 'st-1.day=>dt'
200+
assert_equal Time.local(2005,10,28,4,3), Time.local(2005,10,29,4,3,0).ago(24.hours), 'dt-1.day=>dt'
201201
end
202202
with_env_tz 'NZ' do
203203
# st: New Zealand: 2006 March 19th 4:03am
204-
assert_equal Time.local(2006,3,18,4,3), Time.local(2006,3,19,4,3,0).ago(86400), 'st-1.day=>dt'
205-
assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(86400), 'dt-1.day=>dt'
204+
assert_equal Time.local(2006,3,18,5,3), Time.local(2006,3,19,4,3,0).ago(24.hours), 'st-1.day=>dt'
205+
assert_equal Time.local(2006,3,17,4,3), Time.local(2006,3,18,4,3,0).ago(24.hours), 'dt-1.day=>dt'
206206
end
207207
end
208208

@@ -243,13 +243,13 @@ def test_since
243243
def test_daylight_savings_time_crossings_forward_start
244244
with_env_tz 'US/Eastern' do
245245
# st: US: 2005 April 2nd 7:27pm
246-
assert_equal Time.local(2005,4,3,19,27,0), Time.local(2005,4,2,19,27,0).since(86400), 'st+1.day=>dt'
247-
assert_equal Time.local(2005,4,4,19,27,0), Time.local(2005,4,3,19,27,0).since(86400), 'dt+1.day=>dt'
246+
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'
247+
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'
248248
end
249249
with_env_tz 'NZ' do
250250
# st: New Zealand: 2006 September 30th 7:27pm
251-
assert_equal Time.local(2006,10,1,19,27,0), Time.local(2006,9,30,19,27,0).since(86400), 'st+1.day=>dt'
252-
assert_equal Time.local(2006,10,2,19,27,0), Time.local(2006,10,1,19,27,0).since(86400), 'dt+1.day=>dt'
251+
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'
252+
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'
253253
end
254254
end
255255

@@ -295,13 +295,13 @@ def test_daylight_savings_time_crossings_backward_start_yesterday
295295
def test_daylight_savings_time_crossings_forward_end
296296
with_env_tz 'US/Eastern' do
297297
# dt: US: 2005 October 30th 12:45am
298-
assert_equal Time.local(2005,10,31,0,45,0), Time.local(2005,10,30,0,45,0).since(86400), 'dt+1.day=>st'
299-
assert_equal Time.local(2005,11, 1,0,45,0), Time.local(2005,10,31,0,45,0).since(86400), 'st+1.day=>st'
298+
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'
299+
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'
300300
end
301301
with_env_tz 'NZ' do
302302
# dt: New Zealand: 2006 March 19th 1:45am
303-
assert_equal Time.local(2006,3,20,1,45,0), Time.local(2006,3,19,1,45,0).since(86400), 'dt+1.day=>st'
304-
assert_equal Time.local(2006,3,21,1,45,0), Time.local(2006,3,20,1,45,0).since(86400), 'st+1.day=>st'
303+
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'
304+
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'
305305
end
306306
end
307307

0 commit comments

Comments
 (0)