Skip to content

Commit 5a73782

Browse files
lukellmannilya-g
authored andcommitted
Fix adding small Duration to large Instant on JS and Native
When adding a positive Duration < 1 second to an Instant far in the future for which the addition implementation overflows and throws an exception, the catch blocks would only check if the seconds component of the Duration is > 0. However since the Duration is < 1 second, the seconds component is not > 0 and Instant.MIN is returned instead of Instant.MAX. This was fixed by replacing the check against the seconds component of the Duration with a check against the whole Duration like it was already done in the JVM implementation. See #263
1 parent cbbe4b2 commit 5a73782

File tree

3 files changed

+12
-3
lines changed

3 files changed

+12
-3
lines changed

core/common/test/InstantTest.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,4 +609,13 @@ class InstantRangeTest {
609609
(maxValidInstant + 1.nanoseconds).until(maxValidInstant, DateTimeUnit.NANOSECOND)
610610
maxValidInstant.until(maxValidInstant + 1.nanoseconds, DateTimeUnit.NANOSECOND)
611611
}
612+
613+
// https://github.com/Kotlin/kotlinx-datetime/issues/263
614+
@Test
615+
fun addSmallDurationsToLargeInstants() {
616+
for (smallDuration in listOf(1.nanoseconds, 999_999.nanoseconds, 1.seconds - 1.nanoseconds)) {
617+
assertEquals(expected = Instant.MAX, actual = Instant.MAX + smallDuration)
618+
assertEquals(expected = Instant.MIN, actual = Instant.MIN - smallDuration)
619+
}
620+
}
612621
}

core/js/src/Instant.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public actual class Instant internal constructor(internal val value: jtInstant)
3535
Instant(plusFix(seconds.toDouble(), nanoseconds))
3636
} catch (e: Throwable) {
3737
if (!e.isJodaDateTimeException()) throw e
38-
if (seconds > 0) MAX else MIN
38+
if (duration.isPositive()) MAX else MIN
3939
}
4040
}
4141

core/native/src/Instant.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ public actual class Instant internal constructor(public actual val epochSeconds:
159159
try {
160160
plus(secondsToAdd, nanosecondsToAdd.toLong())
161161
} catch (e: IllegalArgumentException) {
162-
if (secondsToAdd > 0) MAX else MIN
162+
if (duration.isPositive()) MAX else MIN
163163
} catch (e: ArithmeticException) {
164-
if (secondsToAdd > 0) MAX else MIN
164+
if (duration.isPositive()) MAX else MIN
165165
}
166166
}
167167

0 commit comments

Comments
 (0)