diff --git a/CHANGELOG.md b/CHANGELOG.md index f3e6eb787870..a0eb285ad9a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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: diff --git a/spec/ruby/core/time/localtime_spec.rb b/spec/ruby/core/time/localtime_spec.rb index 609b6532a16c..93fb16e84403 100644 --- a/spec/ruby/core/time/localtime_spec.rb +++ b/spec/ruby/core/time/localtime_spec.rb @@ -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) diff --git a/spec/tags/core/time/getlocal_tags.txt b/spec/tags/core/time/getlocal_tags.txt index 86ed81235d89..c5c99290ae87 100644 --- a/spec/tags/core/time/getlocal_tags.txt +++ b/spec/tags/core/time/getlocal_tags.txt @@ -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 diff --git a/spec/tags/core/time/new_tags.txt b/spec/tags/core/time/new_tags.txt index c8e3291dfc72..bac0b74973de 100644 --- a/spec/tags/core/time/new_tags.txt +++ b/spec/tags/core/time/new_tags.txt @@ -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 diff --git a/src/main/ruby/truffleruby/core/type.rb b/src/main/ruby/truffleruby/core/type.rb index dade0c975b24..92c7152533e3 100644 --- a/src/main/ruby/truffleruby/core/type.rb +++ b/src/main/ruby/truffleruby/core/type.rb @@ -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