What arithmetic and comparison operations does kotlin.time.Duration support, and how does multiplying or dividing durations behave?
answer
- duration / duration => Double ratio (gotcha)
- duration * / scalar => Duration
- Comparable: <, >, ==, ranges all work
- Equality is span-based: 1.seconds == 1000.milliseconds
- INFINITE saturates; indeterminate forms throw
basics
~20 sYou can add and subtract two durations, multiply or divide a duration by a number, divide one duration by another to get a ratio, negate it, and compare them with < or >. Durations also implement Comparable.
solid answer
~40 sDuration is a Comparable<Duration> with full operator support. You can add/subtract two durations (5.seconds + 100.milliseconds), negate (-d) or use unaryMinus, and take absoluteValue. Scaling: duration * Int/Double and duration / Int/Double return a Duration. Dividing two durations (a / b) returns a plain Double ratio — useful for 'how many times does b fit in a'. Comparison uses the Comparable contract so <, >, ==, and ranges work. Helpful predicates: isPositive(), isNegative(), isInfinite(), isFinite(). Edge cases: Duration.INFINITE absorbs finite arithmetic (INFINITE + 5.seconds == INFINITE), multiplying INFINITE by 0 or dividing INFINITE / INFINITE yields NaN-like results that throw, and overflow saturates toward INFINITE rather than wrapping. Equality compares the actual time span, so 1000.milliseconds == 1.seconds is true.
code
kotlin · 12 linesimport kotlin.time.Duration.Companion.seconds
import kotlin.time.Duration.Companion.milliseconds
fun main() {
val a = 10.seconds
val b = 4.seconds
println(a / b) // 2.5 (Double ratio)
println(a * 2) // 20s (Duration)
println(a > b) // true
println(1.seconds == 1000.milliseconds) // true
println((-a).absoluteValue) // 10s
}go deeper
Knows you can add, subtract, and compare durations with normal operators.
Distinguishes scaling (×/÷ scalar -> Duration) from ratio (÷ duration -> Double) and knows equality is span-based.
Explains saturation toward INFINITE on overflow, indeterminate forms throwing, and the predicate helpers.
Reasons about Duration arithmetic as a small algebra (typed dimensional analysis) and its overflow-safety guarantees vs raw Long math in concurrency/timeout code.
## Operators on Duration `Duration` implements `Comparable<Duration>` and overloads a rich operator set. Key distinction: **adding/subtracting** combine two durations, **scaling** combines a duration with a scalar, and **dividing two durations** yields a scalar. ### Additive operators ```kotlin val total = 5.seconds + 100.milliseconds // 5.1s val diff = 1.minutes - 10.seconds // 50s val neg = -diff // unaryMinus -> -50s val abs = neg.absoluteValue // 50s ``` ### Scaling (duration ⊗ scalar -> Duration) ```kotlin val doubled = 5.seconds * 2 // 10s (operator times) val third = 9.seconds / 3 // 3s (operator div by Int/Double) ``` Both `Int` and `Double` scalars are supported on `times` and `div`. ### Ratio (duration / duration -> Double) ```kotlin val ratio: Double = 10.seconds / 4.seconds // 2.5 (how many 4s fit in 10s) ``` This overload returns a **Double**, not a Duration — a common gotcha. Use it for proportions/percentages. ### Comparison & equality Because `Duration` is `Comparable`, `<`, `>`, `<=`, `>=`, `==`, `coerceIn`, `min`/`max`, and ranges all work. **Equality is value-based on the actual span**, so unit doesn't matter: ```kotlin println(1.seconds == 1000.milliseconds) // true println(60.seconds > 1.minutes) // false (equal) ``` ### Predicates `isPositive()`, `isNegative()`, `isInfinite()`, `isFinite()` cover the sign/finiteness checks instead of comparing to `Duration.ZERO` by hand (though comparing to ZERO also works). ### Infinity & saturation - `Duration.INFINITE` behaves like a positive infinity: `INFINITE + 5.seconds == INFINITE`. - Arithmetic **saturates** toward `INFINITE`/`-INFINITE` on overflow rather than silently wrapping a Long. - Indeterminate forms (e.g. `INFINITE * 0`, `INFINITE / INFINITE`) throw `IllegalArgumentException` because the result is undefined. ### Why it matters Value-based equality and the typed ratio operator make duration math safe and expressive — you never accidentally compare millis-as-Long to seconds-as-Long.
- What does 10.seconds / 4.seconds return, and why is its type surprising?It returns a Double, 2.5 — the ratio of the two spans. People expect a Duration, but dividing a span by a span is dimensionless.
- What happens on arithmetic overflow of a Duration?It saturates to Duration.INFINITE (or -INFINITE) rather than wrapping the underlying Long, so you get a clearly-infinite value instead of a corrupted one.
saying these in an interview costs you the question
- Thinking duration / duration returns a Duration instead of a Double
- Assuming Duration equality is unit-sensitive (it is value/span-based)
- Claiming overflow wraps like a Long rather than saturating to INFINITE
- Forgetting Duration is Comparable, so < / > / ranges work directly