From 48ce45e22fe315b81dcfbf2f4d1217f636c626bd Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Tue, 31 Oct 2023 17:32:40 +0100 Subject: [PATCH] [stdlib] Fix outdated documentation in Kotlin-Java Duration conversions Add tests for documentation statements --- .../src/kotlin/time/DurationConversions.kt | 8 ++++--- .../jdk8/test/time/DurationConversionTest.kt | 21 +++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/libraries/stdlib/jdk8/src/kotlin/time/DurationConversions.kt b/libraries/stdlib/jdk8/src/kotlin/time/DurationConversions.kt index 09db7341140..7c206cd2800 100644 --- a/libraries/stdlib/jdk8/src/kotlin/time/DurationConversions.kt +++ b/libraries/stdlib/jdk8/src/kotlin/time/DurationConversions.kt @@ -11,8 +11,10 @@ package kotlin.time /** * Converts [java.time.Duration][java.time.Duration] value to [kotlin.time.Duration][Duration] value. * - * Durations less than 104 days are converted exactly, and durations greater than that can lose some precision - * due to rounding. + * Accuracy of conversion: + * - Durations in range of ±146 years are converted exactly. + * - Durations out of that range, but in range of ±146 million years can be rounded to millisecond precision. + * - Durations greater than that are converted to a positive or negative infinite Duration (see [Duration.INFINITE]). */ @SinceKotlin("1.6") @WasExperimental(ExperimentalTime::class) @@ -24,7 +26,7 @@ public inline fun java.time.Duration.toKotlinDuration(): Duration = /** * Converts [kotlin.time.Duration][Duration] value to [java.time.Duration][java.time.Duration] value. * - * Durations greater than [Long.MAX_VALUE] seconds are cut to that value. + * An infinite duration is converted to either [Long.MAX_VALUE], or [Long.MIN_VALUE] seconds, depending on its sign. */ @SinceKotlin("1.6") @WasExperimental(ExperimentalTime::class) diff --git a/libraries/stdlib/jdk8/test/time/DurationConversionTest.kt b/libraries/stdlib/jdk8/test/time/DurationConversionTest.kt index 6933585d6ff..0bea81c4c3a 100644 --- a/libraries/stdlib/jdk8/test/time/DurationConversionTest.kt +++ b/libraries/stdlib/jdk8/test/time/DurationConversionTest.kt @@ -9,8 +9,8 @@ import kotlin.random.Random import kotlin.test.* import kotlin.time.* import kotlin.time.Duration.Companion.days +import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.nanoseconds -import kotlin.time.Duration.Companion.seconds import java.time.Duration as JTDuration class DurationConversionTest { @@ -34,7 +34,7 @@ class DurationConversionTest { repeat(100) { test( - days = Random.nextInt(-100, 100), + days = Random.nextInt(-146 * 365, 146 * 365), hours = Random.nextInt(-48, 48), minutes = Random.nextInt(-600, 600), seconds = Random.nextInt(-600, 600), @@ -54,22 +54,31 @@ class DurationConversionTest { val duration2 = jtDuration1.toKotlinDuration() assertEquals(duration1, duration2) assertEquals((365 * 150).days, duration2) + + val jtMaxDuration = JTDuration.ofSeconds(Long.MAX_VALUE, 999_999_999) + assertEquals(Duration.INFINITE, jtMaxDuration.toKotlinDuration()) + + val jtMinDuration = JTDuration.ofSeconds(Long.MIN_VALUE, 0) + assertEquals(-Duration.INFINITE, jtMinDuration.toKotlinDuration()) } @Test fun kotlinToJavaClamping() { - val duration = Long.MAX_VALUE.seconds * 5 - val jtDuration = duration.toJavaDuration() + val finiteDuration = (Long.MAX_VALUE / 2 - 1).milliseconds + val jtFiniteDuration = finiteDuration.toJavaDuration() + assertEquals(JTDuration.ofMillis(finiteDuration.inWholeMilliseconds), jtFiniteDuration) + + val jtDuration = Duration.INFINITE.toJavaDuration() assertEquals(JTDuration.ofSeconds(Long.MAX_VALUE), jtDuration) - val jtnegDuration = (-duration).toJavaDuration() + val jtnegDuration = (-Duration.INFINITE).toJavaDuration() assertEquals(JTDuration.ofSeconds(Long.MIN_VALUE), jtnegDuration) } @Test fun randomIsoConversionEquivalence() { repeat(100) { - val duration = Random.nextLong(-(1L shl 53) + 1, 1L shl 53).nanoseconds + val duration = Random.nextLong().nanoseconds val fromString = JTDuration.parse(duration.toIsoString()) val fromDuration = duration.toJavaDuration()