The complexity of this is tiny, here's the whole thing:
public fun LocalTime.truncateTo(unit: DateTimeUnit.TimeBased): LocalTime =
LocalTime.fromNanosecondOfDay(toNanosecondOfDay().let { it - it % unit.nanoseconds })
public fun LocalDateTime.truncateTo(unit: DateTimeUnit.TimeBased): LocalDateTime =
LocalDateTime(date, time.truncateTo(unit))
Here are some tests to make sure it works:
@Test
fun testTruncation() {
val localTime = LocalTime(1, 2, 3, 456789123)
assertEquals(LocalTime(1, 2, 3, 456789123), localTime.truncateTo(DateTimeUnit.NANOSECOND))
assertEquals(LocalTime(1, 2, 3, 456789000), localTime.truncateTo(DateTimeUnit.MICROSECOND))
assertEquals(LocalTime(1, 2, 3, 456000000), localTime.truncateTo(DateTimeUnit.MILLISECOND))
assertEquals(LocalTime(1, 2, 3, 0), localTime.truncateTo(DateTimeUnit.SECOND))
assertEquals(LocalTime(1, 2, 0, 0), localTime.truncateTo(DateTimeUnit.MINUTE))
assertEquals(LocalTime(1, 0, 0, 0), localTime.truncateTo(DateTimeUnit.HOUR))
}
The complexity is in making this consistent with the more general request of temporal adjusters:
https://github.com/Kotlin/kotlinx-datetime/issues/235 This requires careful considerations and thorough design.