Skip to content

Commit 9d65a2e

Browse files
KT-82901: Fix issue with converting Long.MIN_VALUE to Duration
- Fix Duration unit conversion overflow handling for milliseconds and add boundary clamping - Add boundary value tests for Long-to-Duration conversions ^KT-82901 Fixed Merge-request: KT-MR-24754 Merged-by: Dmitry Nekrasov <dmitry.nekrasov@jetbrains.com> (cherry picked from commit ab1a3c3)
1 parent 35a9a82 commit 9d65a2e

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

libraries/stdlib/src/kotlin/time/Duration.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,12 @@ public fun Long.toDuration(unit: DurationUnit): Duration {
977977
val maxNsInUnit = convertDurationUnitOverflow(MAX_NANOS, DurationUnit.NANOSECONDS, unit)
978978
return when {
979979
this in -maxNsInUnit..maxNsInUnit -> durationOfNanos(convertDurationUnitOverflow(this, unit, DurationUnit.NANOSECONDS))
980-
unit >= DurationUnit.MILLISECONDS -> durationOfMillis(this.sign * convertDurationUnitToMilliseconds(abs(this), unit))
980+
unit >= DurationUnit.MILLISECONDS -> durationOfMillis(
981+
this.sign * convertDurationUnitToMilliseconds(
982+
abs(this.coerceAtLeast(Long.MIN_VALUE + 1)),
983+
unit
984+
)
985+
)
981986
else -> durationOfMillis(convertDurationUnit(this, unit, DurationUnit.MILLISECONDS).coerceIn(-MAX_MILLIS, MAX_MILLIS))
982987
}
983988
}

libraries/stdlib/test/time/DurationTest.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,30 @@ class DurationTest {
7575
assertFailsWith<IllegalArgumentException> { Double.NaN.toDuration(DurationUnit.SECONDS) }
7676
}
7777

78+
@Test
79+
fun longBoundaryValuesDurationConversion() {
80+
val testCases = listOf(
81+
Long.MIN_VALUE to Duration.NEG_INFINITE,
82+
Long.MAX_VALUE to Duration.INFINITE
83+
)
84+
85+
for ((value, expectedInfinite) in testCases) {
86+
assertEquals(expectedInfinite, value.days)
87+
assertEquals(expectedInfinite, value.hours)
88+
assertEquals(expectedInfinite, value.minutes)
89+
assertEquals(expectedInfinite, value.seconds)
90+
assertEquals(expectedInfinite, value.milliseconds)
91+
}
92+
93+
val usDuration = 106751991.days + 4.hours + 54.seconds + 775.milliseconds
94+
assertEquals(-usDuration, Long.MIN_VALUE.microseconds)
95+
assertEquals(usDuration, Long.MAX_VALUE.microseconds)
96+
97+
val nsDuration = 106751.days + 23.hours + 47.minutes + 16.seconds + 854.milliseconds
98+
assertEquals(-nsDuration, Long.MIN_VALUE.nanoseconds)
99+
assertEquals(nsDuration, Long.MAX_VALUE.nanoseconds)
100+
}
101+
78102
@Test
79103
fun equality() {
80104
val data = listOf<Pair<Double, DurationUnit>>(

0 commit comments

Comments
 (0)