From 255c4b405ea2f8604e3b94ac894b07d8558f6679 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Tue, 29 Jun 2021 03:42:35 +0300 Subject: [PATCH] Duration: round Double value to Long ns instead of truncating it KT-47675 --- libraries/stdlib/src/kotlin/time/Duration.kt | 5 +++-- libraries/stdlib/test/time/DurationTest.kt | 8 ++++---- libraries/stdlib/test/time/TestTimeSourceTest.kt | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libraries/stdlib/src/kotlin/time/Duration.kt b/libraries/stdlib/src/kotlin/time/Duration.kt index c74ff74fdf9..ab43b56f38e 100644 --- a/libraries/stdlib/src/kotlin/time/Duration.kt +++ b/libraries/stdlib/src/kotlin/time/Duration.kt @@ -9,6 +9,7 @@ import kotlin.contracts.* import kotlin.jvm.JvmInline import kotlin.math.abs import kotlin.math.roundToInt +import kotlin.math.roundToLong import kotlin.math.sign /** @@ -816,11 +817,11 @@ public fun Long.toDuration(unit: DurationUnit): Duration { public fun Double.toDuration(unit: DurationUnit): Duration { val valueInNs = convertDurationUnit(this, unit, DurationUnit.NANOSECONDS) require(!valueInNs.isNaN()) { "Duration value cannot be NaN." } - val nanos = valueInNs.toLong() + val nanos = valueInNs.roundToLong() return if (nanos in -MAX_NANOS..MAX_NANOS) { durationOfNanos(nanos) } else { - val millis = convertDurationUnit(this, unit, DurationUnit.MILLISECONDS).toLong() + val millis = convertDurationUnit(this, unit, DurationUnit.MILLISECONDS).roundToLong() durationOfMillisNormalized(millis) } } diff --git a/libraries/stdlib/test/time/DurationTest.kt b/libraries/stdlib/test/time/DurationTest.kt index 0ac24b03b78..792b4ffbbba 100644 --- a/libraries/stdlib/test/time/DurationTest.kt +++ b/libraries/stdlib/test/time/DurationTest.kt @@ -466,10 +466,10 @@ class DurationTest { assertEquals("PT0.001S", Duration.milliseconds(1).toIsoString()) assertEquals("PT0.000001S", Duration.microseconds(1).toIsoString()) assertEquals("PT0.000000001S", Duration.nanoseconds(1).toIsoString()) + assertEquals("PT0.000000001S", Duration.nanoseconds(0.9).toIsoString()) // rounded to zero assertEquals("PT0S", Duration.nanoseconds(0.1).toIsoString()) - assertEquals("PT0S", Duration.nanoseconds(0.9).toIsoString()) // several units combined assertEquals("PT24H1M", (Duration.days(1) + Duration.minutes(1)).toIsoString()) @@ -558,7 +558,7 @@ class DurationTest { test(Duration.minutes(17.5), "17m 30s") test(Duration.minutes(16.5), "16m 30s") - test(Duration.seconds(1097.1), "18m 17.099999999s") // Double to Long ns truncation! + test(Duration.seconds(1097.1), "18m 17.100s") test(Duration.seconds(90.36), "1m 30.360s") test(Duration.seconds(50), "50s") test(Duration.seconds(1.3), "1.300s") @@ -574,9 +574,9 @@ class DurationTest { test(Duration.microseconds(75.35), "0.000075350s") test(Duration.microseconds(7.25), "0.000007250s") test(Duration.microseconds(1.035), "0.000001035s") - test(Duration.microseconds(1.005), "0.000001004s") // Double to Long ns truncation! + test(Duration.microseconds(1.005), "0.000001005s") - test(Duration.nanoseconds(950.5), "0.000000950s") + test(Duration.nanoseconds(950.5), "0.000000951s") test(Duration.nanoseconds(85.23), "0.000000085s") test(Duration.nanoseconds(8.235), "0.000000008s") test(Duration.nanoseconds(1.3), "0.000000001s") diff --git a/libraries/stdlib/test/time/TestTimeSourceTest.kt b/libraries/stdlib/test/time/TestTimeSourceTest.kt index e40c1cb88d0..209af7306b4 100644 --- a/libraries/stdlib/test/time/TestTimeSourceTest.kt +++ b/libraries/stdlib/test/time/TestTimeSourceTest.kt @@ -51,12 +51,12 @@ class TestTimeSourceTest { val mark = timeSource.markNow() repeat(10_000) { - timeSource += Duration.nanoseconds(0.9) + timeSource += Duration.nanoseconds(0.4) assertEquals(Duration.ZERO, mark.elapsedNow()) } timeSource += Duration.nanoseconds(1.9) - assertEquals(Duration.nanoseconds(1), mark.elapsedNow()) + assertEquals(Duration.nanoseconds(2), mark.elapsedNow()) } }