Skip to content

Commit

Permalink
Support timezone argument to Time.new and Time#{getlocal,localtime}
Browse files Browse the repository at this point in the history
closes oracle#1717

For compatibility with https://bugs.ruby-lang.org/issues/14850

Co-authored-by: Manef Zahra <[email protected]>
Co-authored-by: Patrick Lin <[email protected]>
  • Loading branch information
3 people committed Dec 12, 2024
1 parent 373a3c9 commit 5796698
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Compatibility:
* Add `Dir.for_fd` (#3681, @andrykonchin).
* Add `Dir.fchdir` (#3681, @andrykonchin).
* Add `Dir#chdir` (#3681, @andrykonchin).
* Support Timezone argument to `Time.{new,at}` and `Time#{getlocal,localtime}` (#1717, @patricklinpl, @manefz, @rwstauner).

Performance:

Expand Down
11 changes: 11 additions & 0 deletions spec/ruby/core/time/localtime_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@
end
end

describe "with an argument that responds to #utc_to_local" do
it "coerces using #utc_to_local" do
o = mock('string')
o.should_receive(:utc_to_local).and_return(Time.new(2007, 1, 9, 13, 0, 0, 3600))
t = Time.gm(2007, 1, 9, 12, 0, 0)
t.localtime(o)
t.should == Time.new(2007, 1, 9, 13, 0, 0, 3600)
t.utc_offset.should == 3600
end
end

it "raises ArgumentError if the String argument is not of the form (+|-)HH:MM" do
t = Time.now
-> { t.localtime("3600") }.should raise_error(ArgumentError)
Expand Down
2 changes: 0 additions & 2 deletions spec/tags/core/time/getlocal_tags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ fails:Time#getlocal with an argument that responds to #to_r coerces using #to_r
fails:Time#getlocal raises ArgumentError if the argument represents a value less than or equal to -86400 seconds
fails:Time#getlocal raises ArgumentError if the argument represents a value greater than or equal to 86400 seconds
fails:Time#getlocal with a timezone argument returns a Time in the timezone
fails:Time#getlocal with a timezone argument accepts timezone argument that must have #local_to_utc and #utc_to_local methods
fails:Time#getlocal with a timezone argument raises TypeError if timezone does not implement #utc_to_local method
fails:Time#getlocal with a timezone argument does not raise exception if timezone does not implement #local_to_utc method
fails:Time#getlocal with a timezone argument subject's class implements .find_timezone method calls .find_timezone to build a time object if passed zone name as a timezone argument
fails:Time#getlocal with a timezone argument subject's class implements .find_timezone method does not call .find_timezone if passed any not string/numeric/timezone timezone argument
1 change: 0 additions & 1 deletion spec/tags/core/time/new_tags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ fails:Time.new with a utc_offset argument with an argument that responds to #to_
fails:Time.new with a utc_offset argument raises ArgumentError if the argument represents a value less than or equal to -86400 seconds
fails:Time.new with a utc_offset argument raises ArgumentError if the argument represents a value greater than or equal to 86400 seconds
fails:Time.new with a timezone argument returns a Time in the timezone
fails:Time.new with a timezone argument accepts timezone argument that must have #local_to_utc and #utc_to_local methods
fails:Time.new with a timezone argument raises TypeError if timezone does not implement #local_to_utc method
fails:Time.new with a timezone argument does not raise exception if timezone does not implement #utc_to_local method
fails:Time.new with a timezone argument the #abbr method is used by '%Z' in #strftime
Expand Down
2 changes: 2 additions & 0 deletions src/main/ruby/truffleruby/core/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,8 @@ def self.coerce_to_utc_offset(offset)

if Primitive.is_a? offset, String
offset = Truffle::Type.coerce_string_to_utc_offset(offset)
elsif Primitive.respond_to?(offset, :utc_to_local, false)
offset = offset.utc_to_local(Time.now).utc_offset
else
offset = Truffle::Type.coerce_to_exact_num(offset)
end
Expand Down

0 comments on commit 5796698

Please sign in to comment.