diff --git a/core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt b/core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt index c8c650257d..8126292138 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt @@ -64,6 +64,17 @@ abstract class TimeWindow { */ abstract val midpoint: Instant? + /** + * Returns the duration between [fromTime] and [untilTime] if both are non-null. Otherwise returns null. + */ + val length: Duration? get() { + return if (fromTime == null || untilTime == null) { + null + } else { + Duration.between(fromTime, untilTime) + } + } + /** Returns true iff the given [instant] is within the time interval of this [TimeWindow]. */ abstract operator fun contains(instant: Instant): Boolean diff --git a/core/src/test/kotlin/net/corda/core/contracts/TimeWindowTest.kt b/core/src/test/kotlin/net/corda/core/contracts/TimeWindowTest.kt index 453b01eb65..f0da2499b9 100644 --- a/core/src/test/kotlin/net/corda/core/contracts/TimeWindowTest.kt +++ b/core/src/test/kotlin/net/corda/core/contracts/TimeWindowTest.kt @@ -1,9 +1,12 @@ package net.corda.core.contracts +import net.corda.core.internal.div +import net.corda.core.internal.times import net.corda.core.utilities.millis import net.corda.core.utilities.minutes import org.assertj.core.api.Assertions.assertThat import org.junit.Test +import java.time.Duration import java.time.Instant import java.time.LocalDate import java.time.ZoneOffset.UTC @@ -17,6 +20,7 @@ class TimeWindowTest { assertThat(timeWindow.fromTime).isEqualTo(now) assertThat(timeWindow.untilTime).isNull() assertThat(timeWindow.midpoint).isNull() + assertThat(timeWindow.length).isNull() assertThat(timeWindow.contains(now - 1.millis)).isFalse() assertThat(timeWindow.contains(now)).isTrue() assertThat(timeWindow.contains(now + 1.millis)).isTrue() @@ -28,6 +32,7 @@ class TimeWindowTest { assertThat(timeWindow.fromTime).isNull() assertThat(timeWindow.untilTime).isEqualTo(now) assertThat(timeWindow.midpoint).isNull() + assertThat(timeWindow.length).isNull() assertThat(timeWindow.contains(now - 1.millis)).isTrue() assertThat(timeWindow.contains(now)).isFalse() assertThat(timeWindow.contains(now + 1.millis)).isFalse() @@ -42,6 +47,7 @@ class TimeWindowTest { assertThat(timeWindow.fromTime).isEqualTo(fromTime) assertThat(timeWindow.untilTime).isEqualTo(untilTime) assertThat(timeWindow.midpoint).isEqualTo(today.atTime(12, 15).toInstant(UTC)) + assertThat(timeWindow.length).isEqualTo(Duration.between(fromTime, untilTime)) assertThat(timeWindow.contains(fromTime - 1.millis)).isFalse() assertThat(timeWindow.contains(fromTime)).isTrue() assertThat(timeWindow.contains(fromTime + 1.millis)).isTrue() @@ -51,17 +57,21 @@ class TimeWindowTest { @Test fun fromStartAndDuration() { - val timeWindow = TimeWindow.fromStartAndDuration(now, 10.minutes) + val duration = 10.minutes + val timeWindow = TimeWindow.fromStartAndDuration(now, duration) assertThat(timeWindow.fromTime).isEqualTo(now) - assertThat(timeWindow.untilTime).isEqualTo(now + 10.minutes) - assertThat(timeWindow.midpoint).isEqualTo(now + 5.minutes) + assertThat(timeWindow.untilTime).isEqualTo(now + duration) + assertThat(timeWindow.midpoint).isEqualTo(now + duration / 2) + assertThat(timeWindow.length).isEqualTo(duration) } @Test fun withTolerance() { - val timeWindow = TimeWindow.withTolerance(now, 10.minutes) - assertThat(timeWindow.fromTime).isEqualTo(now - 10.minutes) - assertThat(timeWindow.untilTime).isEqualTo(now + 10.minutes) + val tolerance = 10.minutes + val timeWindow = TimeWindow.withTolerance(now, tolerance) + assertThat(timeWindow.fromTime).isEqualTo(now - tolerance) + assertThat(timeWindow.untilTime).isEqualTo(now + tolerance) assertThat(timeWindow.midpoint).isEqualTo(now) + assertThat(timeWindow.length).isEqualTo(tolerance * 2) } } diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 0931e57561..ddc74beb2a 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -46,6 +46,9 @@ UNRELEASED allows services to start flows marked with the ``StartableByService`` annotation. For backwards compatability service classes with only ``ServiceHub`` constructors will still work. +* ``TimeWindow`` now has a ``length`` property that returns the length of the time-window, or ``null`` if the + time-window is open-ended. + .. _changelog_v1: Release 1.0