From 3b989cc8155a962225f69fd26bb69577ca21d349 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Mon, 3 Jun 2019 19:18:36 +0300 Subject: [PATCH] Avoid using 'D' component in ISO duration string representation Days in ISO have nominal duration, they are not always equal to 24H --- libraries/stdlib/src/kotlin/time/Duration.kt | 49 +++++++++----------- libraries/stdlib/test/time/DurationTest.kt | 10 ++-- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/libraries/stdlib/src/kotlin/time/Duration.kt b/libraries/stdlib/src/kotlin/time/Duration.kt index 6e28afc3ab8..0b84c934432 100644 --- a/libraries/stdlib/src/kotlin/time/Duration.kt +++ b/libraries/stdlib/src/kotlin/time/Duration.kt @@ -156,36 +156,29 @@ public inline class Duration internal constructor(internal val value: Double) : fun toIsoString(): String = buildString { if (isNegative()) append('-') - append('P') - absoluteValue.toComponents { days, hours, minutes, seconds, nanoseconds -> - if (days != 0) - append(days).append('D') - - - if (days == 0 || seconds != 0 || nanoseconds != 0 || minutes != 0 || hours != 0) { - append('T') - val hasHours = hours != 0 || days != 0 - val hasSeconds = seconds != 0 || nanoseconds != 0 - val hasMinutes = minutes != 0 || (hasSeconds && hasHours) - if (hasHours) { - append(hours).append('H') - } - if (hasMinutes) { - append(minutes).append('M') - } - if (hasSeconds || (!hasHours && !hasMinutes)) { - append(seconds) - if (nanoseconds != 0) { - append('.') - val nss = nanoseconds.toString().padStart(9, '0') - when { - nanoseconds % 1_000_000 == 0 -> append(nss, 0, 3) - nanoseconds % 1_000 == 0 -> append(nss, 0, 6) - else -> append(nss) - } + append("PT") + absoluteValue.toComponents { hours, minutes, seconds, nanoseconds -> + val hasHours = hours != 0 + val hasSeconds = seconds != 0 || nanoseconds != 0 + val hasMinutes = minutes != 0 || (hasSeconds && hasHours) + if (hasHours) { + append(hours).append('H') + } + if (hasMinutes) { + append(minutes).append('M') + } + if (hasSeconds || (!hasHours && !hasMinutes)) { + append(seconds) + if (nanoseconds != 0) { + append('.') + val nss = nanoseconds.toString().padStart(9, '0') + when { + nanoseconds % 1_000_000 == 0 -> append(nss, 0, 3) + nanoseconds % 1_000 == 0 -> append(nss, 0, 6) + else -> append(nss) } - append('S') } + append('S') } } } diff --git a/libraries/stdlib/test/time/DurationTest.kt b/libraries/stdlib/test/time/DurationTest.kt index 72a8b91871c..6cbd633c0a0 100644 --- a/libraries/stdlib/test/time/DurationTest.kt +++ b/libraries/stdlib/test/time/DurationTest.kt @@ -254,7 +254,7 @@ class DurationTest { assertEquals("PT0S", Duration.ZERO.toIsoString()) // single unit - assertEquals("P1D", 1.days.toIsoString()) + assertEquals("PT24H", 1.days.toIsoString()) assertEquals("PT1H", 1.hours.toIsoString()) assertEquals("PT1M", 1.minutes.toIsoString()) assertEquals("PT1S", 1.seconds.toIsoString()) @@ -267,9 +267,9 @@ class DurationTest { assertEquals("PT0S", 0.9.nanoseconds.toIsoString()) // several units combined - assertEquals("P1DT0H1M", (1.days + 1.minutes).toIsoString()) - assertEquals("P1DT0H0M1S", (1.days + 1.seconds).toIsoString()) - assertEquals("P1DT0H0M0.001S", (1.days + 1.milliseconds).toIsoString()) + assertEquals("PT24H1M", (1.days + 1.minutes).toIsoString()) + assertEquals("PT24H0M1S", (1.days + 1.seconds).toIsoString()) + assertEquals("PT24H0M0.001S", (1.days + 1.milliseconds).toIsoString()) assertEquals("PT1H30M", (1.hours + 30.minutes).toIsoString()) assertEquals("PT1H0M0.500S", (1.hours + 500.milliseconds).toIsoString()) assertEquals("PT2M0.500S", (2.minutes + 500.milliseconds).toIsoString()) @@ -277,7 +277,7 @@ class DurationTest { // negative assertEquals("-PT23H45M", (-1.days + 15.minutes).toIsoString()) - assertEquals("-P1DT0H15M", (-1.days - 15.minutes).toIsoString()) + assertEquals("-PT24H15M", (-1.days - 15.minutes).toIsoString()) // infinite assertEquals("PT2147483647H", Duration.INFINITE.toIsoString())