https://kotlinlang.org logo
#stdlib
Title
# stdlib
z

Zoltan Demant

02/22/2023, 10:55 AM
How can I refactor this to instead use
kotlin.time.Duration
? I thought this would be simple (it probably still is) but my first attempt didnt result in the behavior I was expecting, and Im not 100% clear on why that is (code for that in 🧵).
Copy code
fun round(
    duration: Long,
    period: Long = 1000,
): Long {
    val half = period / 2
    return (duration + half) / period * period
}
This does not produce the same results:
Copy code
fun round(
    duration: Duration,
    period: Duration = 1.seconds,
): Duration {
    val half = period / 2
    return (duration + half) / period * period
}
s

Szymon Jeziorski

02/22/2023, 11:51 AM
in your original function with duration as Long,
(duration + half) / period
uses Long division meaning that entire decimal section is cut out, so that for example
(9800 + 500) / 1000
gives 10, whereas
Duration / Duration
uses double division meaning above example would give 10.3. If you want version with
Duration
to give same results as the one with
Long
you may for example use
floor
to ignore decimal part of division:
floor((duration + half) / period) * period
k

Klitos Kyriacou

02/22/2023, 12:11 PM
It uses Long (not double) division, but represents the durations in nanoseconds. So, one way to do it is this:
Copy code
val periodNanos = period.inWholeNanoseconds
    return ((duration + period / 2).inWholeNanoseconds / periodNanos * periodNanos).nanoseconds
s

Szymon Jeziorski

02/22/2023, 12:35 PM
k

Klitos Kyriacou

02/22/2023, 12:38 PM
@Szymon Jeziorski you're right. I was looking at
Duration.div(Int)
instead. So it uses Long division for
val half = period / 2
but indeed it uses Double division for dividing by
period
.
z

Zoltan Demant

02/22/2023, 1:00 PM
Thank you both, that makes perfect sense! 🙏🏽
5 Views