Skip to content

Commit 47ba61a

Browse files
committed
[GR-19220] Add spec for small Rational passed to Time::at (#2288)
PullRequest: truffleruby/2480
2 parents c6bdf79 + 63002e9 commit 47ba61a

File tree

2 files changed

+24
-14
lines changed

2 files changed

+24
-14
lines changed

spec/ruby/core/time/at_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@
3838
Time.at(BigDecimal('1.1')).to_f.should == 1.1
3939
end
4040
end
41+
42+
describe "passed Rational" do
43+
it "returns Time with correct microseconds" do
44+
t = Time.at(Rational(1_486_570_508_539_759, 1_000_000))
45+
t.usec.should == 539_759
46+
t.nsec.should == 539_759_000
47+
end
48+
49+
it "returns Time with correct nanoseconds" do
50+
t = Time.at(Rational(1_486_570_508_539_759_123, 1_000_000_000))
51+
t.usec.should == 539_759
52+
t.nsec.should == 539_759_123
53+
end
54+
end
4155
end
4256

4357
describe "passed Time" do

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

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,11 @@ def _dump(limit = nil)
300300
private :_dump
301301

302302
class << self
303-
def at(sec, usec=undefined, unit=undefined, **kwargs)
303+
def at(sec, sub_sec=undefined, unit=undefined, **kwargs)
304304
# **kwargs is used here because 'in' is a ruby keyword
305305
offset = kwargs[:in] ? Truffle::Type.coerce_to_utc_offset(kwargs[:in]) : nil
306306

307-
result = if Primitive.undefined?(usec)
307+
result = if Primitive.undefined?(sub_sec)
308308
if Primitive.object_kind_of?(sec, Time)
309309
copy = allocate
310310
copy.send(:initialize_copy, sec)
@@ -321,11 +321,11 @@ def at(sec, usec=undefined, unit=undefined, **kwargs)
321321
return result
322322
end
323323

324-
if Primitive.object_kind_of?(sec, Time) && Primitive.object_kind_of?(usec, Integer)
324+
if Primitive.object_kind_of?(sec, Time) && Primitive.object_kind_of?(sub_sec, Integer)
325325
raise TypeError, "can't convert Time into an exact number"
326326
end
327327

328-
second_arg_scale =
328+
sub_sec_scale =
329329
if Primitive.undefined?(unit) || :microsecond == unit || :usec == unit
330330
1_000
331331
elsif :millisecond == unit
@@ -336,21 +336,17 @@ def at(sec, usec=undefined, unit=undefined, **kwargs)
336336
raise ArgumentError, "unexpected unit: #{unit}"
337337
end
338338

339-
usec = 0 if Primitive.undefined?(usec)
339+
sec = Truffle::Type.coerce_to_exact_num(sec)
340+
sub_sec = Primitive.undefined?(sub_sec) ? 0 : Truffle::Type.coerce_to_exact_num(sub_sec)
340341

341-
s = Truffle::Type.coerce_to_exact_num(sec)
342-
u = Truffle::Type.coerce_to_exact_num(usec)
342+
seconds, sec_frac = sec.divmod(1)
343343

344-
sec = s.to_i
345-
nsec_frac = s % 1.0
344+
nsec = (sec_frac * 1_000_000_000).round + (sub_sec * sub_sec_scale).to_i
346345

347-
sec -= 1 if s < 0 && nsec_frac > 0
348-
nsec = (nsec_frac * 1_000_000_000 + 0.5).to_i + (u * second_arg_scale).to_i
349-
350-
sec += nsec / 1_000_000_000
346+
seconds += nsec / 1_000_000_000
351347
nsec %= 1_000_000_000
352348

353-
time = Primitive.time_at self, sec, nsec
349+
time = Primitive.time_at self, seconds, nsec
354350
time = Primitive.time_localtime(time, offset) if offset
355351
time
356352
end

0 commit comments

Comments
 (0)