kotlinx-datetime
kotlinx-datetime copied to clipboard
Previous/next date and/or time with the given form
"I have a date or a time, and I want to round/adjust it."
Examples:
- Find the last time it was Monday (or Sunday) not later than the given date: https://github.com/Kotlin/kotlinx-datetime/issues/129#issuecomment-1152301045
- Given the local time, find the 1-hour slot it matches (13:45:12.513 -> 13:00:00.000): https://github.com/Kotlin/kotlinx-datetime/issues/223#issuecomment-1484976078
- Discard the sub-minute components when formatting a
Duration: https://github.com/Kotlin/kotlinx-datetime/issues/225#issuecomment-1240884960 (can also be solved by tweaking the formatter). - Find the next time a given day of the week happens: https://github.com/Kotlin/kotlinx-datetime/issues/235#issuecomment-1336388102
- Internally, we need functions like "find the last Sunday in the given month" to calculate the moments when timezone transitions happen.
One practical use case for such functionality: the OCPP specification. It mandates that ISO date/time strings don't have more than 3 decimal points:
number of decimal places SHALL NOT exceed the maximum of 3.
In other words: no more than millisecond precision.
While working with kotlinx-datetime, we actually ran into compatibility problems with vendors that will flat out reject the nanosecond-precise ISO date/time strings that kotlinx.datetime.Instant gets serialized to by kotlinx.serialization.
We could use JSR-310 (java.time) instead, so we could solve it with truncateTo, or we can write a helper function as suggested on StackOverflow, but I was kind of hoping that there would be an equally convenient built-in multiplatform solution for this.
Update:
I found a single-line workaround for forcibly reducing the precision to millisecond-level in serialized ISO date/time strings, at least for timestamps originating from the system clock:
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
// Will have 6 digits behind the decimal point on Kotlin/JVM, but 3 digits on Kotlin/JS and Kotlin/Native
println(Clock.System.now())
// Will have 3 digits behind the decimal point on Kotlin/JVM, Kotlin/JS and Kotlin/Native
println(Instant.fromEpochMilliseconds(Clock.System.now().toEpochMilliseconds()))
So Kotlin/JVM appears to appears to be the only Kotlin platform that creates Instants from the system clock at nanosecond precision, although I haven't tried it with Kotlin for Android yet.
@volkert-fastned, since your problem is with system interoperability, the upcoming API for parsing and formatting may solve it: https://github.com/Kotlin/kotlinx-datetime/pull/343