Skip to content

Commit 6e62e89

Browse files
sikachujosevalim
authored andcommitted
Fix bug that causes TimeZone.seconds_to_utc_offset to returns wrong offset when hour < 0 and not in hundreds [#3741 status:resolved]
Signed-off-by: José Valim <jose.valim@gmail.com>
1 parent d2759d1 commit 6e62e89

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

activesupport/lib/active_support/values/time_zone.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ class TimeZone
172172
MAPPING.freeze
173173
end
174174

175-
UTC_OFFSET_WITH_COLON = '%+03d:%02d'
175+
UTC_OFFSET_WITH_COLON = '%s%02d:%02d'
176176
UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.sub(':', '')
177177

178178
# Assumes self represents an offset from UTC in seconds (as returned from Time#utc_offset)
@@ -181,9 +181,10 @@ class TimeZone
181181
# TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00"
182182
def self.seconds_to_utc_offset(seconds, colon = true)
183183
format = colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON
184-
hours = seconds / 3600
184+
sign = (seconds < 0 ? '-' : '+')
185+
hours = seconds.abs / 3600
185186
minutes = (seconds.abs % 3600) / 60
186-
format % [hours, minutes]
187+
format % [sign, hours, minutes]
187188
end
188189

189190
include Comparable

activesupport/test/time_zone_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ def test_seconds_to_utc_offset_without_colon
208208
assert_equal "+0000", ActiveSupport::TimeZone.seconds_to_utc_offset(0, false)
209209
assert_equal "+0500", ActiveSupport::TimeZone.seconds_to_utc_offset(18_000, false)
210210
end
211+
212+
def test_seconds_to_utc_offset_with_negative_offset
213+
assert_equal "-01:00", ActiveSupport::TimeZone.seconds_to_utc_offset(-3_600)
214+
assert_equal "-00:59", ActiveSupport::TimeZone.seconds_to_utc_offset(-3_599)
215+
assert_equal "-05:30", ActiveSupport::TimeZone.seconds_to_utc_offset(-19_800)
216+
end
211217

212218
def test_formatted_offset_positive
213219
zone = ActiveSupport::TimeZone['Moscow']

0 commit comments

Comments
 (0)