Store Duration value as a multi-range Long
Now precision loss happens at bigger durations. This changes the binary API due different underlying type of Duration.
This commit is contained in:
@@ -8,9 +8,20 @@ package kotlin.time
|
||||
import kotlin.contracts.*
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sign
|
||||
|
||||
@OptIn(ExperimentalTime::class)
|
||||
private inline val storageUnit get() = DurationUnit.NANOSECONDS
|
||||
private const val MAX_LONG_63 = Long.MAX_VALUE / 2
|
||||
private const val MIN_LONG_63 = Long.MIN_VALUE / 2
|
||||
private const val NANOS_IN_MILLIS = 1_000_000
|
||||
private const val MAX_MILLIS_IN_NANOS = MAX_LONG_63 / NANOS_IN_MILLIS
|
||||
private const val MIN_MILLIS_IN_NANOS = MIN_LONG_63 / NANOS_IN_MILLIS
|
||||
|
||||
private fun nanosToMillis(value: Long): Long = value / NANOS_IN_MILLIS
|
||||
private fun millisToNanos(value: Long): Long = value * NANOS_IN_MILLIS
|
||||
private fun storeAsMillis(value: Long): Long = (value shl 1) + 1
|
||||
private fun storeAsNanos(value: Long): Long = value shl 1
|
||||
private fun storeAs(value: Long, unitValue: Long): Long = (value shl 1) + (unitValue and 1)
|
||||
|
||||
/**
|
||||
* Represents the amount of time one instant of time is away from another instant.
|
||||
@@ -18,7 +29,10 @@ private inline val storageUnit get() = DurationUnit.NANOSECONDS
|
||||
* A negative duration is possible in a situation when the second instant is earlier than the first one.
|
||||
* An infinite duration value [Duration.INFINITE] can be used to represent infinite timeouts.
|
||||
*
|
||||
* To construct a duration use either the extension function [toDuration] available on [Int], [Long], and [Double] numeric types,
|
||||
* The type can store duration values up to ±146 years with nanosecond precision,
|
||||
* and up to ±146 million years with millisecond precision.
|
||||
*
|
||||
* To construct a duration, use either the extension function [toDuration] available on [Int], [Long], and [Double] numeric types,
|
||||
* or the `Duration` companion object functions [Duration.hours], [Duration.minutes], [Duration.seconds], and so on,
|
||||
* taking [Int], [Long], or [Double] numbers as parameters.
|
||||
*
|
||||
@@ -29,17 +43,23 @@ private inline val storageUnit get() = DurationUnit.NANOSECONDS
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalTime
|
||||
@JvmInline
|
||||
public value class Duration internal constructor(internal val value: Double) : Comparable<Duration> {
|
||||
public value class Duration internal constructor(internal val rawValue: Long) : Comparable<Duration> {
|
||||
|
||||
private fun isInNanos() = rawValue and 1L == 0L
|
||||
private fun isInMillis() = rawValue and 1L == 1L
|
||||
private val value: Long get() = rawValue shr 1
|
||||
private val storageUnit get() = if (isInNanos()) DurationUnit.NANOSECONDS else DurationUnit.MILLISECONDS
|
||||
|
||||
init {
|
||||
require(!value.isNaN()) { "Duration value cannot be NaN." }
|
||||
// TODO: assert invariants
|
||||
}
|
||||
|
||||
companion object {
|
||||
/** The duration equal to exactly 0 seconds. */
|
||||
public val ZERO: Duration = Duration(0.0)
|
||||
public val ZERO: Duration = Duration(0L)
|
||||
|
||||
/** The duration whose value is positive infinity. It is useful for representing timeouts that should never expire. */
|
||||
public val INFINITE: Duration = Duration(Double.POSITIVE_INFINITY)
|
||||
public val INFINITE: Duration = Duration(storeAsMillis(MAX_LONG_63))
|
||||
|
||||
/** Converts the given time duration [value] expressed in the specified [sourceUnit] into the specified [targetUnit]. */
|
||||
public fun convert(value: Double, sourceUnit: DurationUnit, targetUnit: DurationUnit): Double =
|
||||
@@ -162,69 +182,218 @@ public value class Duration internal constructor(internal val value: Double) : C
|
||||
// arithmetic operators
|
||||
|
||||
/** Returns the negative of this value. */
|
||||
public operator fun unaryMinus(): Duration = Duration((-value).normalizeZero())
|
||||
public operator fun unaryMinus(): Duration {
|
||||
val value = value
|
||||
return when {
|
||||
rawValue == INFINITE.rawValue -> // negate positive infinite to negative infinite
|
||||
Duration(storeAsMillis(MIN_LONG_63))
|
||||
value != MIN_LONG_63 ->
|
||||
Duration(storeAs(-value, rawValue))
|
||||
isInNanos() -> // negating MIN_VALUE in nanos overflows to millisecond units
|
||||
Duration(storeAsMillis(-nanosToMillis(value)))
|
||||
else -> // negating negative infinity overflows to positive infinity
|
||||
INFINITE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a duration whose value is the sum of this and [other] duration values.
|
||||
*
|
||||
* @throws IllegalArgumentException if the operation results in a `NaN` value.
|
||||
* @throws IllegalArgumentException if the operation results in an undefined value for the given arguments,
|
||||
* e.g. when adding infinite durations of different sign.
|
||||
*/
|
||||
public operator fun plus(other: Duration): Duration = Duration(value + other.value)
|
||||
public operator fun plus(other: Duration): Duration {
|
||||
when {
|
||||
this.isInfinite() -> {
|
||||
if (other.isFinite() || (this.rawValue xor other.rawValue >= 0))
|
||||
return this
|
||||
else
|
||||
throw IllegalArgumentException("Sum of infinite durations of different signs is undefined.")
|
||||
}
|
||||
other.isInfinite() -> return other
|
||||
}
|
||||
|
||||
return if (this.isInNanos() == other.isInNanos()) {
|
||||
when (val newValue = this.value + other.value) { // never overflows long, but can overflow long63
|
||||
in MIN_LONG_63..MAX_LONG_63 -> {
|
||||
if (isInMillis() && newValue in MIN_MILLIS_IN_NANOS..MAX_MILLIS_IN_NANOS)
|
||||
Duration(storeAsNanos(millisToNanos(newValue)))
|
||||
else
|
||||
Duration(storeAs(newValue, this.rawValue))
|
||||
}
|
||||
else -> {
|
||||
val millisValue = if (isInNanos()) nanosToMillis(newValue) else newValue.coerceIn(MIN_LONG_63, MAX_LONG_63)
|
||||
Duration(storeAsMillis(millisValue))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val a: Long
|
||||
val b: Long
|
||||
if (this.isInMillis()) {
|
||||
a = this.value
|
||||
b = other.value
|
||||
} else {
|
||||
a = other.value
|
||||
b = this.value
|
||||
}
|
||||
|
||||
val bMillis = nanosToMillis(b)
|
||||
val resultMillis = a + bMillis
|
||||
return if (resultMillis in MIN_MILLIS_IN_NANOS..MAX_MILLIS_IN_NANOS) {
|
||||
val bRemainder = b - millisToNanos(bMillis)
|
||||
Duration(storeAsNanos(millisToNanos(resultMillis) + bRemainder)) // can it overflow nanos?
|
||||
} else {
|
||||
Duration(storeAsMillis(resultMillis.coerceIn(MIN_LONG_63, MAX_LONG_63)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a duration whose value is the difference between this and [other] duration values.
|
||||
*
|
||||
* @throws IllegalArgumentException if the operation results in a `NaN` value.
|
||||
* @throws IllegalArgumentException if the operation results in an undefined value for the given arguments,
|
||||
* e.g. when subtracting infinite durations of the same sign.
|
||||
*/
|
||||
public operator fun minus(other: Duration): Duration = Duration(value - other.value)
|
||||
// TODO: negation may overflow
|
||||
public operator fun minus(other: Duration): Duration = this + (-other)
|
||||
|
||||
/**
|
||||
* Returns a duration whose value is this duration value multiplied by the given [scale] number.
|
||||
*
|
||||
* @throws IllegalArgumentException if the operation results in a `NaN` value.
|
||||
* @throws IllegalArgumentException if the operation results in an undefined value for the given arguments,
|
||||
* e.g. when multiplying an infinite duration by zero.
|
||||
*/
|
||||
public operator fun times(scale: Int): Duration = Duration((value * scale).normalizeZero())
|
||||
public operator fun times(scale: Int): Duration {
|
||||
if (isInfinite()) {
|
||||
return when {
|
||||
scale == 0 -> throw IllegalArgumentException("Multiplying infinite duration by zero is undefined.")
|
||||
scale > 0 -> this
|
||||
else -> -this
|
||||
}
|
||||
}
|
||||
if (scale == 0) return ZERO
|
||||
|
||||
val result = value * scale
|
||||
if (value >= Int.MIN_VALUE && value <= Int.MAX_VALUE) {
|
||||
return Duration(storeAs(result, rawValue))
|
||||
}
|
||||
if (result / scale != value && isInNanos()) { // Long overflow
|
||||
val rawMillis = nanosToMillis(value)
|
||||
val resultMillis = rawMillis * scale
|
||||
if (resultMillis / scale != rawMillis) return Duration.INFINITE
|
||||
return when {
|
||||
resultMillis in MIN_LONG_63..MAX_LONG_63 -> Duration(storeAsMillis(resultMillis))
|
||||
resultMillis > 0 -> Duration.INFINITE
|
||||
else -> -Duration.INFINITE
|
||||
}
|
||||
}
|
||||
|
||||
return when {
|
||||
result in MIN_LONG_63..MAX_LONG_63 -> {
|
||||
Duration(storeAs(result, rawValue))
|
||||
}
|
||||
isInNanos() -> {
|
||||
Duration(storeAsMillis(nanosToMillis(result)))
|
||||
}
|
||||
result > 0 -> Duration.INFINITE
|
||||
else -> -Duration.INFINITE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a duration whose value is this duration value multiplied by the given [scale] number.
|
||||
*
|
||||
* @throws IllegalArgumentException if the operation results in a `NaN` value.
|
||||
* @throws IllegalArgumentException if the operation results in an undefined value for the given arguments,
|
||||
* e.g. when multiplying an infinite duration by zero.
|
||||
*/
|
||||
public operator fun times(scale: Double): Duration = Duration((value * scale).normalizeZero())
|
||||
public operator fun times(scale: Double): Duration {
|
||||
val intScale = scale.roundToInt()
|
||||
if (intScale.toDouble() == scale) {
|
||||
return times(intScale)
|
||||
}
|
||||
|
||||
val unit = storageUnit
|
||||
val result = toDouble(unit) * scale
|
||||
return result.toDuration(unit)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a duration whose value is this duration value divided by the given [scale] number.
|
||||
*
|
||||
* @throws IllegalArgumentException if the operation results in a `NaN` value.
|
||||
* @throws IllegalArgumentException if the operation results in an undefined value for the given arguments,
|
||||
* e.g. when dividing zero duration by zero.
|
||||
*/
|
||||
public operator fun div(scale: Int): Duration = Duration((value / scale).normalizeZero())
|
||||
public operator fun div(scale: Int): Duration {
|
||||
if (scale == 0) {
|
||||
return when {
|
||||
isPositive() -> Duration.INFINITE
|
||||
isNegative() -> -Duration.INFINITE
|
||||
else -> throw IllegalArgumentException("Dividing zero duration by zero is undefined")
|
||||
}
|
||||
}
|
||||
if (isInNanos()) {
|
||||
return Duration(storeAsNanos(value / scale))
|
||||
} else {
|
||||
if (isInfinite())
|
||||
return this * scale.sign
|
||||
|
||||
val result = value / scale
|
||||
|
||||
if (result in MIN_MILLIS_IN_NANOS..MAX_MILLIS_IN_NANOS) {
|
||||
// TODO: more precise
|
||||
return Duration(storeAsNanos(millisToNanos(result)))
|
||||
}
|
||||
return Duration(storeAsMillis(result))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a duration whose value is this duration value divided by the given [scale] number.
|
||||
*
|
||||
* @throws IllegalArgumentException if the operation results in a `NaN` value.
|
||||
* @throws IllegalArgumentException if the operation results in an undefined value for the given arguments,
|
||||
* e.g. when dividing an infinite duration by infinity or zero duration by zero.
|
||||
*/
|
||||
public operator fun div(scale: Double): Duration = Duration((value / scale).normalizeZero())
|
||||
public operator fun div(scale: Double): Duration {
|
||||
if (scale != 0.0) {
|
||||
val intScale = scale.roundToInt()
|
||||
if (intScale.toDouble() == scale) {
|
||||
return div(intScale)
|
||||
}
|
||||
}
|
||||
val unit = storageUnit
|
||||
val result = toDouble(unit) / scale
|
||||
return result.toDuration(unit)
|
||||
}
|
||||
|
||||
/** Returns a number that is the ratio of this and [other] duration values. */
|
||||
public operator fun div(other: Duration): Double = this.value / other.value
|
||||
public operator fun div(other: Duration): Double {
|
||||
val coarserUnit = maxOf(this.storageUnit, other.storageUnit)
|
||||
return this.toDouble(coarserUnit) / other.toDouble(coarserUnit)
|
||||
}
|
||||
|
||||
/** Returns true, if the duration value is less than zero. */
|
||||
public fun isNegative(): Boolean = value < 0
|
||||
public fun isNegative(): Boolean = rawValue < 0
|
||||
|
||||
/** Returns true, if the duration value is greater than zero. */
|
||||
public fun isPositive(): Boolean = value > 0
|
||||
public fun isPositive(): Boolean = rawValue > 0
|
||||
|
||||
/** Returns true, if the duration value is infinite. */
|
||||
public fun isInfinite(): Boolean = value.isInfinite()
|
||||
public fun isInfinite(): Boolean = isInMillis() && value.let { it == MAX_LONG_63 || it == MIN_LONG_63 }
|
||||
|
||||
/** Returns true, if the duration value is finite. */
|
||||
public fun isFinite(): Boolean = value.isFinite()
|
||||
public fun isFinite(): Boolean = !isInfinite()
|
||||
|
||||
/** Returns the absolute value of this value. The returned value is always non-negative. */
|
||||
public val absoluteValue: Duration get() = if (isNegative()) -this else this
|
||||
|
||||
override fun compareTo(other: Duration): Int = this.value.compareTo(other.value)
|
||||
override fun compareTo(other: Duration): Int {
|
||||
val compareBits = this.rawValue xor other.rawValue
|
||||
if (compareBits < 0 || compareBits and 1L == 0L) // different signs or same sign, same scale
|
||||
return this.rawValue.compareTo(other.rawValue)
|
||||
// same sign, different scales
|
||||
val r = (this.rawValue and 1L).toInt() - (other.rawValue and 1L).toInt()
|
||||
return if (this.rawValue < 0) -r else r
|
||||
}
|
||||
|
||||
|
||||
// splitting to components
|
||||
@@ -304,21 +473,37 @@ public value class Duration internal constructor(internal val value: Double) : C
|
||||
// conversion to units
|
||||
|
||||
/** Returns the value of this duration expressed as a [Double] number of the specified [unit]. */
|
||||
public fun toDouble(unit: DurationUnit): Double = convertDurationUnit(value, storageUnit, unit)
|
||||
public fun toDouble(unit: DurationUnit): Double {
|
||||
return if (isInfinite()) {
|
||||
if (isNegative()) Double.NEGATIVE_INFINITY else Double.POSITIVE_INFINITY
|
||||
} else {
|
||||
// TODO: whether it's ok to convert to Double before scaling
|
||||
convertDurationUnit(value.toDouble(), storageUnit, unit)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this duration expressed as a [Long] number of the specified [unit].
|
||||
*
|
||||
* If the value doesn't fit in the range of [Long] type, it is coerced into that range, see the conversion [Double.toLong] for details.
|
||||
*/
|
||||
public fun toLong(unit: DurationUnit): Long = toDouble(unit).toLong()
|
||||
public fun toLong(unit: DurationUnit): Long {
|
||||
return if (isInfinite()) {
|
||||
if (isNegative()) Long.MIN_VALUE else Long.MAX_VALUE
|
||||
} else {
|
||||
convertDurationUnit(value, storageUnit, unit)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this duration expressed as an [Int] number of the specified [unit].
|
||||
*
|
||||
* If the value doesn't fit in the range of [Int] type, it is coerced into that range, see the conversion [Double.toInt] for details.
|
||||
*/
|
||||
public fun toInt(unit: DurationUnit): Int = toDouble(unit).toInt()
|
||||
public fun toInt(unit: DurationUnit): Int =
|
||||
toLong(unit).coerceIn(Int.MIN_VALUE.toLong(), Int.MAX_VALUE.toLong()).toInt()
|
||||
|
||||
// TODO: inWholeUnits conversions, deprecate inUnits
|
||||
|
||||
/** The value of this duration expressed as a [Double] number of days. */
|
||||
public val inDays: Double get() = toDouble(DurationUnit.DAYS)
|
||||
@@ -350,7 +535,16 @@ public value class Duration internal constructor(internal val value: Double) : C
|
||||
*
|
||||
* The range of durations that can be expressed as a `Long` number of nanoseconds is approximately ±292 years.
|
||||
*/
|
||||
public fun toLongNanoseconds(): Long = toLong(DurationUnit.NANOSECONDS)
|
||||
// TODO: Deprecate in favor inWholeNanoseconds
|
||||
public fun toLongNanoseconds(): Long {
|
||||
val value = value
|
||||
return when {
|
||||
isInNanos() -> value
|
||||
value > Long.MAX_VALUE / NANOS_IN_MILLIS -> Long.MAX_VALUE
|
||||
value < Long.MIN_VALUE / NANOS_IN_MILLIS -> Long.MIN_VALUE
|
||||
else -> millisToNanos(value)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this duration expressed as a [Long] number of milliseconds.
|
||||
@@ -359,7 +553,10 @@ public value class Duration internal constructor(internal val value: Double) : C
|
||||
*
|
||||
* The range of durations that can be expressed as a `Long` number of milliseconds is approximately ±292 million years.
|
||||
*/
|
||||
public fun toLongMilliseconds(): Long = toLong(DurationUnit.MILLISECONDS)
|
||||
// TODO: Deprecate in favor inWholeMilliseconds
|
||||
public fun toLongMilliseconds(): Long {
|
||||
return if (isInMillis() && isFinite()) value else toLong(DurationUnit.MILLISECONDS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this duration value expressed in the unit which yields the most compact and readable number value.
|
||||
@@ -375,8 +572,8 @@ public value class Duration internal constructor(internal val value: Double) : C
|
||||
* @sample samples.time.Durations.toStringDefault
|
||||
*/
|
||||
override fun toString(): String = when {
|
||||
isInfinite() -> value.toString()
|
||||
value == 0.0 -> "0s"
|
||||
isInfinite() -> if (isNegative()) "-Infinity" else "Infinity"
|
||||
rawValue == 0L -> "0s"
|
||||
else -> {
|
||||
val absNs = absoluteValue.inNanoseconds
|
||||
var scientific = false
|
||||
@@ -424,8 +621,8 @@ public value class Duration internal constructor(internal val value: Double) : C
|
||||
*/
|
||||
public fun toString(unit: DurationUnit, decimals: Int = 0): String {
|
||||
require(decimals >= 0) { "decimals must be not negative, but was $decimals" }
|
||||
if (isInfinite()) return value.toString()
|
||||
val number = toDouble(unit)
|
||||
if (number.isInfinite()) return number.toString()
|
||||
return when {
|
||||
abs(number) < 1e14 -> formatToExactDecimals(number, decimals.coerceAtMost(12))
|
||||
else -> formatScientific(number)
|
||||
@@ -485,12 +682,28 @@ public value class Duration internal constructor(internal val value: Double) : C
|
||||
/** Returns a [Duration] equal to this [Int] number of the specified [unit]. */
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalTime
|
||||
public fun Int.toDuration(unit: DurationUnit): Duration = toDouble().toDuration(unit)
|
||||
public fun Int.toDuration(unit: DurationUnit): Duration {
|
||||
return if (unit <= DurationUnit.SECONDS) {
|
||||
Duration(storeAsNanos(convertDurationUnitOverflow(this.toLong(), unit, DurationUnit.NANOSECONDS)))
|
||||
} else
|
||||
toLong().toDuration(unit)
|
||||
}
|
||||
|
||||
/** Returns a [Duration] equal to this [Long] number of the specified [unit]. */
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalTime
|
||||
public fun Long.toDuration(unit: DurationUnit): Duration = toDouble().toDuration(unit)
|
||||
public fun Long.toDuration(unit: DurationUnit): Duration {
|
||||
val maxInUnit = convertDurationUnitOverflow(MAX_LONG_63, DurationUnit.NANOSECONDS, unit)
|
||||
if (this in -maxInUnit..maxInUnit) {
|
||||
return Duration(storeAsNanos(convertDurationUnitOverflow(this, unit, DurationUnit.NANOSECONDS)))
|
||||
} else {
|
||||
val max2InUnit = convertDurationUnitOverflow(MAX_LONG_63, DurationUnit.MILLISECONDS, unit)
|
||||
if (unit < DurationUnit.MILLISECONDS || this in -max2InUnit..max2InUnit) {
|
||||
return Duration(storeAsMillis(convertDurationUnitOverflow(this, unit, DurationUnit.MILLISECONDS)))
|
||||
}
|
||||
return if (this < 0) -Duration.INFINITE else Duration.INFINITE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a [Duration] equal to this [Double] number of the specified [unit].
|
||||
@@ -499,7 +712,15 @@ public fun Long.toDuration(unit: DurationUnit): Duration = toDouble().toDuration
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalTime
|
||||
public fun Double.toDuration(unit: DurationUnit): Duration = Duration(convertDurationUnit(this, unit, storageUnit).normalizeZero())
|
||||
public fun Double.toDuration(unit: DurationUnit): Duration {
|
||||
val valueInNs = convertDurationUnit(this, unit, DurationUnit.NANOSECONDS)
|
||||
require(!valueInNs.isNaN()) { "Duration value cannot be NaN." }
|
||||
return if (valueInNs > MAX_LONG_63 || valueInNs < MIN_LONG_63) {
|
||||
Duration(storeAsMillis((valueInNs / NANOS_IN_MILLIS).toLong().coerceIn(MIN_LONG_63, MAX_LONG_63)))
|
||||
} else {
|
||||
Duration(storeAsNanos(valueInNs.toLong()))
|
||||
}
|
||||
}
|
||||
|
||||
// constructing from number of units
|
||||
// extension properties
|
||||
@@ -675,10 +896,6 @@ public inline operator fun Int.times(duration: Duration): Duration = duration *
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun Double.times(duration: Duration): Duration = duration * this
|
||||
|
||||
|
||||
@kotlin.internal.InlineOnly
|
||||
private inline fun Double.normalizeZero(): Double = this + 0.0
|
||||
|
||||
internal expect fun formatToExactDecimals(value: Double, decimals: Int): String
|
||||
internal expect fun formatUpToDecimals(value: Double, decimals: Int): String
|
||||
internal expect fun formatScientific(value: Double): String
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -52,6 +52,16 @@ public expect enum class DurationUnit {
|
||||
@ExperimentalTime
|
||||
internal expect fun convertDurationUnit(value: Double, sourceUnit: DurationUnit, targetUnit: DurationUnit): Double
|
||||
|
||||
// overflown result is unspecified
|
||||
@SinceKotlin("1.5")
|
||||
@ExperimentalTime
|
||||
internal expect fun convertDurationUnitOverflow(value: Long, sourceUnit: DurationUnit, targetUnit: DurationUnit): Long
|
||||
|
||||
// overflown result is coerced in the Long range boundaries
|
||||
@SinceKotlin("1.5")
|
||||
@ExperimentalTime
|
||||
internal expect fun convertDurationUnit(value: Long, sourceUnit: DurationUnit, targetUnit: DurationUnit): Long
|
||||
|
||||
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalTime
|
||||
|
||||
Reference in New Issue
Block a user