From 7efad77fdea5b73845a7b2198b088ff5effc0eb9 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sat, 27 Jun 2026 23:37:25 +0200 Subject: [PATCH] core-time: add TimeBridge (Instant <-> epoch millis) Generic content-provider time bridge shared by the family: Long epoch millis <-> kotlin.time.Instant. Extracted from Calendula for Phase 1 (Calendula as the second core-time consumer). 3 unit tests; module suite now 5 green. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../jeanlucmakiola/floret/time/TimeBridge.kt | 9 +++++++ .../floret/time/TimeBridgeTest.kt | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 core-time/src/main/kotlin/de/jeanlucmakiola/floret/time/TimeBridge.kt create mode 100644 core-time/src/test/kotlin/de/jeanlucmakiola/floret/time/TimeBridgeTest.kt diff --git a/core-time/src/main/kotlin/de/jeanlucmakiola/floret/time/TimeBridge.kt b/core-time/src/main/kotlin/de/jeanlucmakiola/floret/time/TimeBridge.kt new file mode 100644 index 0000000..c9b193d --- /dev/null +++ b/core-time/src/main/kotlin/de/jeanlucmakiola/floret/time/TimeBridge.kt @@ -0,0 +1,9 @@ +package de.jeanlucmakiola.floret.time + +import kotlin.time.Instant + +/** Epoch milliseconds (as stored by Android content providers) → [Instant]. */ +fun Long.toKotlinInstantFromEpochMillis(): Instant = Instant.fromEpochMilliseconds(this) + +/** [Instant] → epoch milliseconds, for writing back to a content provider. */ +fun Instant.toEpochMillis(): Long = toEpochMilliseconds() diff --git a/core-time/src/test/kotlin/de/jeanlucmakiola/floret/time/TimeBridgeTest.kt b/core-time/src/test/kotlin/de/jeanlucmakiola/floret/time/TimeBridgeTest.kt new file mode 100644 index 0000000..a7f26b2 --- /dev/null +++ b/core-time/src/test/kotlin/de/jeanlucmakiola/floret/time/TimeBridgeTest.kt @@ -0,0 +1,26 @@ +package de.jeanlucmakiola.floret.time + +import com.google.common.truth.Truth.assertThat +import kotlin.time.Instant +import org.junit.jupiter.api.Test + +class TimeBridgeTest { + + @Test + fun `epoch millis round-trips through Instant`() { + val original = 1_717_840_800_000L // 2024-06-08T10:00:00Z + val instant = original.toKotlinInstantFromEpochMillis() + assertThat(instant.toEpochMillis()).isEqualTo(original) + } + + @Test + fun `zero millis maps to Instant epoch`() { + assertThat(0L.toKotlinInstantFromEpochMillis()).isEqualTo(Instant.fromEpochMilliseconds(0L)) + } + + @Test + fun `negative epoch millis is supported`() { + val original = -1_000_000L + assertThat(original.toKotlinInstantFromEpochMillis().toEpochMillis()).isEqualTo(original) + } +}