1515import org .jruby .runtime .ThreadContext ;
1616import org .jruby .runtime .builtin .IRubyObject ;
1717
18+ import java .math .BigInteger ;
19+
1820import static org .jruby .RubyTime .TIME_SCALE ;
1921import static org .jruby .api .Convert .asFixnum ;
2022import static org .jruby .api .Convert .toDouble ;
@@ -129,14 +131,17 @@ public void initializeTime(ThreadContext context, RubyTime time, DateTimeZone dt
129131 var numerator = subSecond .getNumerator ().asLong (context );
130132 var denominator = subSecond .getDenominator ().asLong (context );
131133 if (numerator >= denominator ) {
132- secondsInRational = (int ) (numerator / ( double ) denominator );
134+ secondsInRational = (int ) (numerator / denominator );
133135 numerator = numerator % denominator ;
134- subSecond = RubyRational .newRational (context .runtime , numerator , denominator );
135136 }
136- var subSeconds = subSecond .asDouble (context ) * TIME_SCALE ;
137137
138- millis = (long ) subSeconds / 1_000_000 ;
139- nanos = (long ) subSeconds % 1_000_000 ;
138+ long subSeconds = BigInteger .valueOf (numerator )
139+ .multiply (RubyTime .TIME_SCALE_BI )
140+ .divide (BigInteger .valueOf (denominator ))
141+ .longValue ();
142+
143+ millis = subSeconds / 1_000_000 ;
144+ nanos = subSeconds % 1_000_000 ;
140145 } else {
141146 double secs = toDouble (context , secondObj );
142147
@@ -149,10 +154,10 @@ public void initializeTime(ThreadContext context, RubyTime time, DateTimeZone dt
149154 } else if (usecObj instanceof RubyRational subSecond ) {
150155 if (subSecond .isNegativeNumber (context )) throw argumentError (context , "argument out of range" );
151156
152- var subSeconds = subSecond .asDouble ( context ) * 1_000 ;
157+ long subNanos = subSecond .getNumerator (). asLong ( context ) * 1_000 / subSecond . getDenominator (). asLong ( context ) ;
153158
154- millis = ( long ) subSeconds / 1_000_000 ;
155- nanos = ( long ) subSeconds % 1_000_000 ;
159+ millis = subNanos / 1_000_000 ;
160+ nanos = subNanos % 1_000_000 ;
156161 } else if (usecObj instanceof RubyFloat flo ) {
157162 if (flo .isNegativeNumber (context )) throw argumentError (context , "argument out of range" );
158163
0 commit comments