Skip to content

Commit c951dec

Browse files
andrykonchineregon
authored andcommitted
Fix Marshal.load and keeps Time utc offset
1 parent 10947dc commit c951dec

File tree

3 files changed

+64
-11
lines changed

3 files changed

+64
-11
lines changed

spec/ruby/core/marshal/shared/load.rb

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -940,14 +940,38 @@
940940
t1.should equal t2
941941
end
942942

943-
it "loads the zone" do
943+
it "keeps the local zone" do
944944
with_timezone 'AST', 3 do
945945
t = Time.local(2012, 1, 1)
946946
Marshal.send(@method, Marshal.dump(t)).zone.should == t.zone
947947
end
948948
end
949949

950-
it "loads nanoseconds" do
950+
it "keeps UTC zone" do
951+
t = Time.now.utc
952+
t2 = Marshal.send(@method, Marshal.dump(t))
953+
t2.should.utc?
954+
end
955+
956+
it "keeps the zone" do
957+
t = nil
958+
959+
with_timezone 'AST', 4 do
960+
t = Time.local(2012, 1, 1)
961+
end
962+
963+
with_timezone 'EET', -2 do
964+
Marshal.send(@method, Marshal.dump(t)).zone.should == 'AST'
965+
end
966+
end
967+
968+
it "keeps utc offset" do
969+
t = Time.new(2007,11,1,15,25,0, "+09:00")
970+
t2 = Marshal.send(@method, Marshal.dump(t))
971+
t2.utc_offset.should == 32400
972+
end
973+
974+
it "keeps nanoseconds" do
951975
t = Time.now
952976
Marshal.send(@method, Marshal.dump(t)).nsec.should == t.nsec
953977
end

src/main/java/org/truffleruby/core/time/TimeNodes.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,17 @@ protected Object timeZone(RubyTime time) {
403403
}
404404
}
405405

406+
@Primitive(name = "time_set_zone")
407+
public abstract static class TimeSetZoneNode extends PrimitiveArrayArgumentsNode {
408+
@Specialization(guards = "strings.isRubyString(zone)", limit = "1")
409+
protected Object timeSetZone(RubyTime time, Object zone,
410+
@Cached RubyStringLibrary strings) {
411+
time.zone = zone;
412+
return zone;
413+
}
414+
415+
}
416+
406417
@Primitive(name = "time_strftime")
407418
public abstract static class TimeStrftimePrimitiveNode extends PrimitiveArrayArgumentsNode {
408419

src/main/ruby/truffleruby/core/marshal.rb

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,27 +243,45 @@ def set_instance_variables(obj)
243243
end
244244

245245
def set_time_variables(time)
246-
nano_num = nano_den = nil
246+
nano_num = nano_den = offset = zone = nil
247247

248248
construct_integer.times do
249-
ivar = get_symbol
249+
name = get_symbol
250250
value = construct
251251

252252
case
253-
when ivar == :nano_num
253+
when name == :nano_num
254254
nano_num = value
255-
when ivar == :nano_den
255+
when name == :nano_den
256256
nano_den = value
257-
when ivar.start_with?("@")
258-
Primitive.object_ivar_set time, ivar, value
259-
else
260-
# ignore not regular instance variables (without @ prefix), e.g. :offset, :zone
257+
when name == :offset
258+
offset = value
259+
when name == :zone
260+
zone = value
261+
when name.start_with?('@')
262+
Primitive.object_ivar_set time, name, value
263+
end
264+
end
265+
266+
unless Primitive.nil?(offset)
267+
begin
268+
offset = Truffle::Type.coerce_to_exact_num(offset)
269+
rescue TypeError
270+
offset = nil
261271
end
262272
end
263273

264-
if nano_num && nano_den
274+
unless Primitive.nil?(zone)
275+
zone = Truffle::Type.rb_check_convert_type(zone, String, :to_str)
276+
zone = nil if !Primitive.nil?(zone) && zone.include?("\0")
277+
end
278+
279+
unless Primitive.nil?(nano_num) || Primitive.nil?(nano_den)
265280
Primitive.time_set_nseconds(time, Rational(nano_num, nano_den).to_i)
266281
end
282+
283+
time.localtime offset unless Primitive.nil?(offset)
284+
Primitive.time_set_zone(time, zone) unless Primitive.nil?(zone)
267285
end
268286

269287
STRING_ALLOCATE = String.method(:__allocate__).unbind

0 commit comments

Comments
 (0)