Duration: inWholeUnits properties instead of inUnits
Introduce conversion properties returning Long values, deprecate the old ones returning Doubles.
This commit is contained in:
@@ -26,7 +26,7 @@ import kotlin.math.sign
|
||||
*
|
||||
* To get the value of this duration expressed in a particular [duration units][DurationUnit]
|
||||
* use the functions [toInt], [toLong], and [toDouble]
|
||||
* or the properties [inHours], [inMinutes], [inSeconds], [inNanoseconds], and so on.
|
||||
* or the properties [inWholeHours], [inWholeMinutes], [inWholeSeconds], [inWholeNanoseconds], and so on.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalTime
|
||||
@@ -390,7 +390,7 @@ public value class Duration internal constructor(private val rawValue: Long) : C
|
||||
*/
|
||||
public inline fun <T> toComponents(action: (days: Int, hours: Int, minutes: Int, seconds: Int, nanoseconds: Int) -> T): T {
|
||||
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
|
||||
return action(inDays.toInt(), hoursComponent, minutesComponent, secondsComponent, nanosecondsComponent)
|
||||
return action(toInt(DurationUnit.DAYS), hoursComponent, minutesComponent, secondsComponent, nanosecondsComponent)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -406,7 +406,7 @@ public value class Duration internal constructor(private val rawValue: Long) : C
|
||||
*/
|
||||
public inline fun <T> toComponents(action: (hours: Int, minutes: Int, seconds: Int, nanoseconds: Int) -> T): T {
|
||||
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
|
||||
return action(inHours.toInt(), minutesComponent, secondsComponent, nanosecondsComponent)
|
||||
return action(toInt(DurationUnit.HOURS), minutesComponent, secondsComponent, nanosecondsComponent)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,7 +421,7 @@ public value class Duration internal constructor(private val rawValue: Long) : C
|
||||
*/
|
||||
public inline fun <T> toComponents(action: (minutes: Int, seconds: Int, nanoseconds: Int) -> T): T {
|
||||
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
|
||||
return action(inMinutes.toInt(), secondsComponent, nanosecondsComponent)
|
||||
return action(toInt(DurationUnit.MINUTES), secondsComponent, nanosecondsComponent)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,22 +435,37 @@ public value class Duration internal constructor(private val rawValue: Long) : C
|
||||
*/
|
||||
public inline fun <T> toComponents(action: (seconds: Long, nanoseconds: Int) -> T): T {
|
||||
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
|
||||
return action(inSeconds.toLong(), nanosecondsComponent)
|
||||
return action(inWholeSeconds, nanosecondsComponent)
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal val hoursComponent: Int get() = (inHours % 24).toInt()
|
||||
internal val hoursComponent: Int
|
||||
get() = if (isInfinite()) 0 else (inWholeHours % 24).toInt()
|
||||
|
||||
@PublishedApi
|
||||
internal val minutesComponent: Int get() = (inMinutes % 60).toInt()
|
||||
internal val minutesComponent: Int
|
||||
get() = if (isInfinite()) 0 else (inWholeMinutes % 60).toInt()
|
||||
|
||||
@PublishedApi
|
||||
internal val secondsComponent: Int get() = (inSeconds % 60).toInt()
|
||||
internal val secondsComponent: Int
|
||||
get() = if (isInfinite()) 0 else (inWholeSeconds % 60).toInt()
|
||||
|
||||
@PublishedApi
|
||||
internal val nanosecondsComponent: Int get() = (inNanoseconds % 1e9).toInt()
|
||||
internal val nanosecondsComponent: Int
|
||||
get() = when {
|
||||
isInfinite() -> 0
|
||||
isInMillis() -> millisToNanos(value % 1_000).toInt()
|
||||
else -> (value % 1_000_000_000).toInt()
|
||||
}
|
||||
|
||||
|
||||
// conversion to units
|
||||
|
||||
/** Returns the value of this duration expressed as a [Double] number of the specified [unit]. */
|
||||
/**
|
||||
* Returns the value of this duration expressed as a [Double] number of the specified [unit].
|
||||
*
|
||||
* An infinite duration value is converted either to [Double.POSITIVE_INFINITY] or [Double.NEGATIVE_INFINITY] depending on its sign.
|
||||
*/
|
||||
public fun toDouble(unit: DurationUnit): Double {
|
||||
return when (rawValue) {
|
||||
INFINITE.rawValue -> Double.POSITIVE_INFINITY
|
||||
@@ -465,7 +480,11 @@ public value class Duration internal constructor(private val rawValue: Long) : C
|
||||
/**
|
||||
* 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.
|
||||
* If the result doesn't fit in the range of [Long] type, it is coerced into that range:
|
||||
* - [Long.MIN_VALUE] is returned if it's less than `Long.MIN_VALUE`,
|
||||
* - [Long.MAX_VALUE] is returned if it's greater than `Long.MAX_VALUE`.
|
||||
*
|
||||
* An infinite duration value is converted either to [Long.MAX_VALUE] or [Long.MIN_VALUE] depending on its sign.
|
||||
*/
|
||||
public fun toLong(unit: DurationUnit): Long {
|
||||
return when (rawValue) {
|
||||
@@ -478,34 +497,125 @@ public value class Duration internal constructor(private val rawValue: Long) : C
|
||||
/**
|
||||
* 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.
|
||||
* If the result doesn't fit in the range of [Int] type, it is coerced into that range:
|
||||
* - [Int.MIN_VALUE] is returned if it's less than `Int.MIN_VALUE`,
|
||||
* - [Int.MAX_VALUE] is returned if it's greater than `Int.MAX_VALUE`.
|
||||
*
|
||||
* An infinite duration value is converted either to [Int.MAX_VALUE] or [Int.MIN_VALUE] depending on its sign.
|
||||
*/
|
||||
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. */
|
||||
@Deprecated("Use inWholeDays property instead or convert toDouble(DAYS) if a double value is required.", ReplaceWith("toDouble(DurationUnit.DAYS)"))
|
||||
public val inDays: Double get() = toDouble(DurationUnit.DAYS)
|
||||
|
||||
/** The value of this duration expressed as a [Double] number of hours. */
|
||||
@Deprecated("Use inWholeHours property instead or convert toDouble(HOURS) if a double value is required.", ReplaceWith("toDouble(DurationUnit.HOURS)"))
|
||||
public val inHours: Double get() = toDouble(DurationUnit.HOURS)
|
||||
|
||||
/** The value of this duration expressed as a [Double] number of minutes. */
|
||||
@Deprecated("Use inWholeMinutes property instead or convert toDouble(MINUTES) if a double value is required.", ReplaceWith("toDouble(DurationUnit.MINUTES)"))
|
||||
public val inMinutes: Double get() = toDouble(DurationUnit.MINUTES)
|
||||
|
||||
/** The value of this duration expressed as a [Double] number of seconds. */
|
||||
@Deprecated("Use inWholeSeconds property instead or convert toDouble(SECONDS) if a double value is required.", ReplaceWith("toDouble(DurationUnit.SECONDS)"))
|
||||
public val inSeconds: Double get() = toDouble(DurationUnit.SECONDS)
|
||||
|
||||
/** The value of this duration expressed as a [Double] number of milliseconds. */
|
||||
@Deprecated("Use inWholeMilliseconds property instead or convert toDouble(MILLISECONDS) if a double value is required.", ReplaceWith("toDouble(DurationUnit.MILLISECONDS)"))
|
||||
public val inMilliseconds: Double get() = toDouble(DurationUnit.MILLISECONDS)
|
||||
|
||||
/** The value of this duration expressed as a [Double] number of microseconds. */
|
||||
@Deprecated("Use inWholeMicroseconds property instead or convert toDouble(MICROSECONDS) if a double value is required.", ReplaceWith("toDouble(DurationUnit.MICROSECONDS)"))
|
||||
public val inMicroseconds: Double get() = toDouble(DurationUnit.MICROSECONDS)
|
||||
|
||||
/** The value of this duration expressed as a [Double] number of nanoseconds. */
|
||||
@Deprecated("Use inWholeNanoseconds property instead or convert toDouble(NANOSECONDS) if a double value is required.", ReplaceWith("toDouble(DurationUnit.NANOSECONDS)"))
|
||||
public val inNanoseconds: Double get() = toDouble(DurationUnit.NANOSECONDS)
|
||||
|
||||
|
||||
/**
|
||||
* The value of this duration expressed as a [Long] number of days.
|
||||
*
|
||||
* An infinite duration value is converted either to [Long.MAX_VALUE] or [Long.MIN_VALUE] depending on its sign.
|
||||
*/
|
||||
@SinceKotlin("1.5")
|
||||
public val inWholeDays: Long
|
||||
get() = toLong(DurationUnit.DAYS)
|
||||
|
||||
/**
|
||||
* The value of this duration expressed as a [Long] number of hours.
|
||||
*
|
||||
* An infinite duration value is converted either to [Long.MAX_VALUE] or [Long.MIN_VALUE] depending on its sign.
|
||||
*/
|
||||
@SinceKotlin("1.5")
|
||||
public val inWholeHours: Long
|
||||
get() = toLong(DurationUnit.HOURS)
|
||||
|
||||
/**
|
||||
* The value of this duration expressed as a [Long] number of minutes.
|
||||
*
|
||||
* An infinite duration value is converted either to [Long.MAX_VALUE] or [Long.MIN_VALUE] depending on its sign.
|
||||
*/
|
||||
@SinceKotlin("1.5")
|
||||
public val inWholeMinutes: Long
|
||||
get() = toLong(DurationUnit.MINUTES)
|
||||
|
||||
/**
|
||||
* The value of this duration expressed as a [Long] number of seconds.
|
||||
*
|
||||
* An infinite duration value is converted either to [Long.MAX_VALUE] or [Long.MIN_VALUE] depending on its sign.
|
||||
*/
|
||||
@SinceKotlin("1.5")
|
||||
public val inWholeSeconds: Long
|
||||
get() = toLong(DurationUnit.SECONDS)
|
||||
|
||||
/**
|
||||
* The value of this duration expressed as a [Long] number of milliseconds.
|
||||
*
|
||||
* An infinite duration value is converted either to [Long.MAX_VALUE] or [Long.MIN_VALUE] depending on its sign.
|
||||
*/
|
||||
@SinceKotlin("1.5")
|
||||
public val inWholeMilliseconds: Long
|
||||
get() {
|
||||
return if (isInMillis() && isFinite()) value else toLong(DurationUnit.MILLISECONDS)
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of this duration expressed as a [Long] number of microseconds.
|
||||
*
|
||||
* If the result doesn't fit in the range of [Long] type, it is coerced into that range:
|
||||
* - [Long.MIN_VALUE] is returned if it's less than `Long.MIN_VALUE`,
|
||||
* - [Long.MAX_VALUE] is returned if it's greater than `Long.MAX_VALUE`.
|
||||
*
|
||||
* An infinite duration value is converted either to [Long.MAX_VALUE] or [Long.MIN_VALUE] depending on its sign.
|
||||
*/
|
||||
@SinceKotlin("1.5")
|
||||
public val inWholeMicroseconds: Long
|
||||
get() = toLong(DurationUnit.MICROSECONDS)
|
||||
|
||||
/**
|
||||
* The value of this duration expressed as a [Long] number of nanoseconds.
|
||||
*
|
||||
* If the result doesn't fit in the range of [Long] type, it is coerced into that range:
|
||||
* - [Long.MIN_VALUE] is returned if it's less than `Long.MIN_VALUE`,
|
||||
* - [Long.MAX_VALUE] is returned if it's greater than `Long.MAX_VALUE`.
|
||||
*
|
||||
* An infinite duration value is converted either to [Long.MAX_VALUE] or [Long.MIN_VALUE] depending on its sign.
|
||||
*/
|
||||
@SinceKotlin("1.5")
|
||||
public val inWholeNanoseconds: Long
|
||||
get() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// shortcuts
|
||||
|
||||
/**
|
||||
@@ -515,16 +625,8 @@ public value class Duration internal constructor(private val rawValue: Long) : C
|
||||
*
|
||||
* The range of durations that can be expressed as a `Long` number of nanoseconds is approximately ±292 years.
|
||||
*/
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
@Deprecated("Use inWholeNanoseconds property instead.", ReplaceWith("this.inWholeNanoseconds"))
|
||||
public fun toLongNanoseconds(): Long = inWholeNanoseconds
|
||||
|
||||
/**
|
||||
* Returns the value of this duration expressed as a [Long] number of milliseconds.
|
||||
@@ -533,10 +635,8 @@ public value class Duration internal constructor(private val rawValue: Long) : C
|
||||
*
|
||||
* The range of durations that can be expressed as a `Long` number of milliseconds is approximately ±292 million years.
|
||||
*/
|
||||
// TODO: Deprecate in favor inWholeMilliseconds
|
||||
public fun toLongMilliseconds(): Long {
|
||||
return if (isInMillis() && isFinite()) rawValue else toLong(DurationUnit.MILLISECONDS)
|
||||
}
|
||||
@Deprecated("Use inWholeMilliseconds property instead.", ReplaceWith("this.inWholeMilliseconds"))
|
||||
public fun toLongMilliseconds(): Long = inWholeMilliseconds
|
||||
|
||||
/**
|
||||
* Returns a string representation of this duration value expressed in the unit which yields the most compact and readable number value.
|
||||
@@ -556,7 +656,7 @@ public value class Duration internal constructor(private val rawValue: Long) : C
|
||||
INFINITE.rawValue -> "Infinity"
|
||||
NEG_INFINITE.rawValue -> "-Infinity"
|
||||
else -> {
|
||||
val absNs = absoluteValue.inNanoseconds
|
||||
val absNs = absoluteValue.toDouble(DurationUnit.NANOSECONDS)
|
||||
var scientific = false
|
||||
var maxDecimals = 0
|
||||
val unit = when {
|
||||
|
||||
Reference in New Issue
Block a user