Skip to content

Commit

Permalink
TZ offset minute has to be negated in the Western Hemisphere
Browse files Browse the repository at this point in the history
When the TZ in the given string contains minus offset, both hour and minute
value has to be negated, but the current code negates hour only.
Hence, for instance in Newfoundland Time Zone (UTC−03:30), it used to return
1 hour advanced value.

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
  • Loading branch information
amatsuda and nobu committed Jan 3, 2023
1 parent f517eef commit 30d65b1
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 1 deletion.
5 changes: 5 additions & 0 deletions activemodel/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
* Fix a bug where type casting of string to `Time` and `DateTime` doesn't
calculate minus minute value in TZ offset correctly.

*Akira Matsuda*

* Raise `NoMethodError` in `ActiveModel::Type::Value#as_json` to avoid unpredictable
results.

Expand Down
8 changes: 7 additions & 1 deletion activemodel/lib/active_model/type/helpers/time_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,13 @@ def fast_string_to_time(string)
end

if $8
offset = $8 == "Z" ? 0 : $8.to_i * 3600 + $9.to_i * 60
offset = \
if $8 == "Z"
0
else
offset_h, offset_m = $8.to_i, $9.to_i
offset_h.to_i * 3600 + (offset_h.negative? ? -1 : 1) * offset_m * 60
end
end

new_time($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, usec, offset)
Expand Down
1 change: 1 addition & 0 deletions activemodel/test/cases/type/time_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def test_type_cast_time
assert_equal ::Time.utc(2000, 1, 1, 16, 45, 54), type.cast("2015-06-13T19:45:54+03:00")
assert_equal ::Time.utc(1999, 12, 31, 21, 7, 8), type.cast("06:07:08+09:00")
assert_equal ::Time.utc(2000, 1, 1, 16, 45, 54), type.cast(4 => 16, 5 => 45, 6 => 54)
assert_equal ::Time.utc(2000, 1, 1, 3, 30, 0), type.cast("2023-01-01T00:00:00-03:30")
end

def test_user_input_in_time_zone
Expand Down

0 comments on commit 30d65b1

Please sign in to comment.