diff --git a/libraries/stdlib/samples/test/samples/time/durations.kt b/libraries/stdlib/samples/test/samples/time/durations.kt index 532b320c28a..92dd63f50e3 100644 --- a/libraries/stdlib/samples/test/samples/time/durations.kt +++ b/libraries/stdlib/samples/test/samples/time/durations.kt @@ -30,7 +30,7 @@ class Durations { assertPrints(Duration.minutes(1230), "20h 30m") assertPrints(Duration.minutes(920), "15h 20m") assertPrints(Duration.seconds(1.546), "1.546s") - assertPrints(Duration.milliseconds(25.12), "25.120ms") + assertPrints(Duration.milliseconds(25.12), "25.12ms") } @Sample diff --git a/libraries/stdlib/src/kotlin/time/Duration.kt b/libraries/stdlib/src/kotlin/time/Duration.kt index aa26d08072a..f35d9bcb0e0 100644 --- a/libraries/stdlib/src/kotlin/time/Duration.kt +++ b/libraries/stdlib/src/kotlin/time/Duration.kt @@ -748,11 +748,11 @@ public value class Duration internal constructor(private val rawValue: Long) : C if (components++ > 0) append(' ') when { seconds != 0 || hasDays || hasHours || hasMinutes -> - appendFractional(seconds, nanoseconds, "s") + appendFractional(seconds, nanoseconds, 9, "s", isoZeroes = false) nanoseconds >= 1_000_000 -> - appendFractional(nanoseconds / 1_000_000, nanoseconds % 1_000_000 * 1_000, "ms") + appendFractional(nanoseconds / 1_000_000, nanoseconds % 1_000_000, 6, "ms", isoZeroes = false) nanoseconds >= 1_000 -> - appendFractional(nanoseconds / 1_000, nanoseconds % 1_000 * 1_000_000, "us") + appendFractional(nanoseconds / 1_000, nanoseconds % 1_000, 3, "us", isoZeroes = false) else -> append(nanoseconds).append("ns") } @@ -764,15 +764,15 @@ public value class Duration internal constructor(private val rawValue: Long) : C } } - private fun StringBuilder.appendFractional(whole: Int, nanoFractional: Int, unit: String) { + private fun StringBuilder.appendFractional(whole: Int, fractional: Int, fractionalSize: Int, unit: String, isoZeroes: Boolean) { append(whole) - if (nanoFractional != 0) { + if (fractional != 0) { append('.') - val nanoString = nanoFractional.toString().padStart(9, '0') + val fracString = fractional.toString().padStart(fractionalSize, '0') + val nonZeroDigits = fracString.indexOfLast { it != '0' } + 1 when { - nanoFractional % 1_000_000 == 0 -> appendRange(nanoString, 0, 3) - nanoFractional % 1_000 == 0 -> appendRange(nanoString, 0, 6) - else -> append(nanoString) + !isoZeroes && nonZeroDigits < 3 -> appendRange(fracString, 0, nonZeroDigits) + else -> appendRange(fracString, 0, ((nonZeroDigits + 2) / 3) * 3) } } append(unit) @@ -836,7 +836,7 @@ public value class Duration internal constructor(private val rawValue: Long) : C append(minutes).append('M') } if (hasSeconds || (!hasHours && !hasMinutes)) { - appendFractional(seconds, nanoseconds, "S") + appendFractional(seconds, nanoseconds, 9, "S", isoZeroes = true) } } } diff --git a/libraries/stdlib/test/time/DurationTest.kt b/libraries/stdlib/test/time/DurationTest.kt index cf18376af15..8d7aa273c02 100644 --- a/libraries/stdlib/test/time/DurationTest.kt +++ b/libraries/stdlib/test/time/DurationTest.kt @@ -626,24 +626,24 @@ class DurationTest { test(Duration.minutes(17.5), "17m 30s") test(Duration.minutes(16.5), "16m 30s") - test(Duration.seconds(1097.1), "18m 17.100s") - test(Duration.seconds(90.36), "1m 30.360s") + test(Duration.seconds(1097.1), "18m 17.1s") + test(Duration.seconds(90.36), "1m 30.36s") test(Duration.seconds(50), "50s") - test(Duration.seconds(1.3), "1.300s") + test(Duration.seconds(1.3), "1.3s") test(Duration.seconds(1), "1s") test(Duration.seconds(0.5), "500ms") - test(Duration.milliseconds(40.2), "40.200ms") + test(Duration.milliseconds(40.2), "40.2ms") test(Duration.milliseconds(4.225), "4.225ms") test(Duration.milliseconds(4.24501), "4.245010ms", "4ms 245us 10ns") test(Duration.milliseconds(1), "1ms") test(Duration.milliseconds(0.75), "750us") - test(Duration.microseconds(75.35), "75.350us") - test(Duration.microseconds(7.25), "7.250us") + test(Duration.microseconds(75.35), "75.35us") + test(Duration.microseconds(7.25), "7.25us") test(Duration.microseconds(1.035), "1.035us") test(Duration.microseconds(1.005), "1.005us") - test(Duration.nanoseconds(1800), "1.800us", "1800ns", "0.0000000005h") + test(Duration.nanoseconds(1800), "1.8us", "1800ns", "0.0000000005h") test(Duration.nanoseconds(950.5), "951ns") test(Duration.nanoseconds(85.23), "85ns")