summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--spec/ruby/core/time/plus_spec.rb13
-rw-r--r--test/ruby/test_time_tz.rb6
-rw-r--r--time.c8
4 files changed, 29 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 92eed9798c..a10ecadc5d 100644
--- a/NEWS
+++ b/NEWS
@@ -263,7 +263,8 @@ sufficient information, see the ChangeLog file or Redmine
* New features:
* `Time.new` and `Time#getlocal` accept a timezone object as
- well as UTC offset string. [Feature #14850]
+ well as UTC offset string. `Time#+`, `Time#-` and `Time#succ`
+ also preserve the timezone. [Feature #14850]
* `TracePoint`
diff --git a/spec/ruby/core/time/plus_spec.rb b/spec/ruby/core/time/plus_spec.rb
index 0cf0d11a74..0861e9c9f6 100644
--- a/spec/ruby/core/time/plus_spec.rb
+++ b/spec/ruby/core/time/plus_spec.rb
@@ -47,6 +47,19 @@ describe "Time#+" do
(Time.new(2012, 1, 1, 0, 0, 0, 3600) + 10).utc_offset.should == 3600
end
+ ruby_version_is "2.6" do
+ it "returns a time with the same timezone as self" do
+ zone = mock("timezone")
+ zone.should_receive(:local_to_utc).and_return(Time.utc(2012, 1, 1, 6, 30, 0))
+ zone.should_receive(:utc_to_local).and_return(Time.utc(2012, 1, 1, 12, 0, 10))
+ t = Time.new(2012, 1, 1, 12, 0, 0, zone) + 10
+ t.zone.should == zone
+ t.utc_offset.should == 19800
+ t.to_a[0, 6].should == [10, 0, 12, 1, 1, 2012]
+ t.should == Time.utc(2012, 1, 1, 6, 30, 10)
+ end
+ end
+
it "does not return a subclass instance" do
c = Class.new(Time)
x = c.now + 1
diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb
index c3c272dca3..46bbc8433b 100644
--- a/test/ruby/test_time_tz.rb
+++ b/test/ruby/test_time_tz.rb
@@ -536,4 +536,10 @@ class TestTimeTZ::WithTZ < Test::Unit::TestCase
t = Time.new(2018, 9, 1, 12, 0, 0, tz)
assert_equal("+0900 #{abbr}", t.strftime("%z %Z"))
end
+
+ def test_plus_with_timezone
+ t = Time.new(2018, 9, 1, 12, 0, 0, tz) + 4000
+ assert_equal([2018, 9, 1, 13, 6, 40, tz], [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.zone])
+ assert_equal(Time.utc(2018, 9, 1, 4, 6, 40), t)
+ end
end
diff --git a/time.c b/time.c
index 0b3056bb7a..5ba13efb9e 100644
--- a/time.c
+++ b/time.c
@@ -3899,6 +3899,11 @@ time_add(struct time_object *tobj, VALUE torig, VALUE offset, int sign)
GetTimeval(result, tobj);
TZMODE_SET_FIXOFF(tobj, off);
}
+ else if (TZMODE_LOCALTIME_P(tobj)) {
+ VALUE zone = tobj->vtm.zone;
+ GetTimeval(result, tobj);
+ tobj->vtm.zone = zone;
+ }
return result;
}
@@ -3982,6 +3987,9 @@ rb_time_succ(VALUE time)
time = time_new_timew(rb_cTime, wadd(tobj->timew, WINT2FIXWV(TIME_SCALE)));
GetTimeval(time, tobj2);
TZMODE_COPY(tobj2, tobj);
+ if (TZMODE_LOCALTIME_P(tobj2) && maybe_tzobj_p(tobj2->vtm.zone)) {
+ zone_localtime(tobj2->vtm.zone, time);
+ }
return time;
}