Skip to content

Commit 0e24ce7

Browse files
committed
JS: fix Instant.fromEpochSeconds on extreme values
1 parent 1404222 commit 0e24ce7

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

core/jsMain/src/Instant.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,11 @@ public actual class Instant internal constructor(internal val value: jtInstant)
8080
}
8181

8282
actual fun fromEpochSeconds(epochSeconds: Long, nanosecondAdjustment: Long): Instant = try {
83-
Instant(jtInstant.ofEpochSecond(epochSeconds, nanosecondAdjustment))
83+
val secs = safeAdd(epochSeconds, floorDiv(nanosecondAdjustment, NANOS_PER_ONE.toLong()))
84+
val nos = floorMod(nanosecondAdjustment, NANOS_PER_ONE.toLong()).toInt()
85+
Instant(jtInstant.ofEpochSecond(secs, nos))
8486
} catch (e: Throwable) {
85-
if (!e.isJodaDateTimeException()) throw e
87+
if (!e.isJodaDateTimeException() && e !is ArithmeticException) throw e
8688
if (epochSeconds > 0) MAX else MIN
8789
}
8890

core/jsMain/src/mathJs.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,35 @@ internal actual fun safeMultiply(a: Int, b: Int): Int {
5858
if (result > Int.MAX_VALUE || result < Int.MIN_VALUE) throw ArithmeticException("Multiplication overflows Int range: $a * $b.")
5959
return result.toInt()
6060
}
61+
62+
/**
63+
* Returns the floor division.
64+
* <p>
65+
* This returns {@code 0} for {@code floorDiv(0, 4)}.<br />
66+
* This returns {@code -1} for {@code floorDiv(-1, 4)}.<br />
67+
* This returns {@code -1} for {@code floorDiv(-2, 4)}.<br />
68+
* This returns {@code -1} for {@code floorDiv(-3, 4)}.<br />
69+
* This returns {@code -1} for {@code floorDiv(-4, 4)}.<br />
70+
* This returns {@code -2} for {@code floorDiv(-5, 4)}.<br />
71+
*
72+
* @param a the dividend
73+
* @param b the divisor
74+
* @return the floor division
75+
*/
76+
internal fun floorDiv(a: Long, b: Long): Long = if (a >= 0) a / b else (a + 1) / b - 1
77+
78+
/**
79+
* Returns the floor modulus.
80+
*
81+
*
82+
* This returns `0` for `floorMod(0, 4)`.<br></br>
83+
* This returns `1` for `floorMod(-1, 4)`.<br></br>
84+
* This returns `2` for `floorMod(-2, 4)`.<br></br>
85+
* This returns `3` for `floorMod(-3, 4)`.<br></br>
86+
* This returns `0` for `floorMod(-4, 4)`.<br></br>
87+
*
88+
* @param a the dividend
89+
* @param b the divisor
90+
* @return the floor modulus (positive)
91+
*/
92+
internal fun floorMod(a: Long, b: Long): Long = (a % b + b) % b

0 commit comments

Comments
 (0)