chore(dependency): upgrade kotlinx.datetime to 0.7.0

Resolves #9397.

Updated Kotlinx Datetime to 0.7.0

Updated Kotlinx Datetime to 0.7.0
Kotlinx Datetime needs to be updated to 0.7.0. There are some breaking changes listed in the Release notes that could affect our project.

See also:
- https://github.com/Kotlin/kotlinx-datetime/releases/tag/v0.7.0
- [Deprecation of Instant](https://github.com/Kotlin/kotlinx-datetime?tab=readme-ov-file#deprecation-of-instant)

./gradlew :legacy:ui:legacy:testDebugUnitTest --tests "com.fsck.k9.ui.helper.RelativeDateTimeFormatterTest" --tests "com.fsck.k9.ui.messagelist.MessageListAdapterTest" :core:common:testDebugUnitTest --tests "net.thunderbird.core.common.cache.ExpiringCacheTest" --tests "net.thunderbird.core.common.cache.CacheTest" :core:testing:testDebugUnitTest --tests "net.thunderbird.core.testing.TestClockTest" :legacy:core:testDebugUnitTest --tests "com.fsck.k9.notification.SummaryNotificationDataCreatorTest" --tests "com.fsck.k9.notification.NewMailNotificationManagerTest" --tests "com.fsck.k9.QuietTimeCheckerTest" :feature:funding:googleplay:testDebugUnitTest --tests "app.k9mail.feature.funding.googleplay.ui.reminder.FundingReminderTest" --tests "app.k9mail.feature.funding.googleplay.ui.reminder.ActivityLifecycleObserverTest" :core:logging:api:testDebugUnitTest --tests "net.thunderbird.core.logging.DefaultLoggerTest"

diff --git a/app-common/src/main/kotlin/net/thunderbird/app/common/core/AppCommonCoreModule.kt b/app-common/src/main/kotlin/net/thunderbird/app/common/core/AppCommonCoreModule.kt
index f53aa9a9777..92e1c60d6b3 100644
--- a/app-common/src/main/kotlin/net/thunderbird/app/common/core/AppCommonCoreModule.kt
+++ b/app-common/src/main/kotlin/net/thunderbird/app/common/core/AppCommonCoreModule.kt
@@ -1,6 +1,7 @@
 package net.thunderbird.app.common.core

 import android.content.Context
+import kotlin.time.ExperimentalTime
 import net.thunderbird.app.common.BuildConfig
 import net.thunderbird.core.logging.DefaultLogger
 import net.thunderbird.core.logging.LogLevel
@@ -35,6 +36,7 @@ val appCommonCoreModule: Module = module {
     }

     single<Logger> {
+        @OptIn(ExperimentalTime::class)
         DefaultLogger(
             sink = get<CompositeLogSink>(),
         )
@@ -57,6 +59,7 @@ val appCommonCoreModule: Module = module {
     }

     single<Logger> (named(SYNC_DEBUG_LOG)) {
+        @OptIn(ExperimentalTime::class)
         DefaultLogger(
             sink = get<CompositeLogSink>(named(SYNC_DEBUG_LOG)),
         )
diff --git a/app-k9mail/dependencies/fossReleaseRuntimeClasspath.txt b/app-k9mail/dependencies/fossReleaseRuntimeClasspath.txt
index 06576d9ae59..2fb021c48f7 100644
--- a/app-k9mail/dependencies/fossReleaseRuntimeClasspath.txt
+++ b/app-k9mail/dependencies/fossReleaseRuntimeClasspath.txt
@@ -262,8 +262,8 @@ org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
-org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
-org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
+org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.0
+org.jetbrains.kotlinx:kotlinx-datetime:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
diff --git a/app-k9mail/dependencies/fullReleaseRuntimeClasspath.txt b/app-k9mail/dependencies/fullReleaseRuntimeClasspath.txt
index 8ce56ac10a6..2f0f6e66590 100644
--- a/app-k9mail/dependencies/fullReleaseRuntimeClasspath.txt
+++ b/app-k9mail/dependencies/fullReleaseRuntimeClasspath.txt
@@ -276,8 +276,8 @@ org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
-org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
-org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
+org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.0
+org.jetbrains.kotlinx:kotlinx-datetime:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
diff --git a/app-thunderbird/dependencies/fossBetaRuntimeClasspath.txt b/app-thunderbird/dependencies/fossBetaRuntimeClasspath.txt
index 3779b618d81..3d2667bc6af 100644
--- a/app-thunderbird/dependencies/fossBetaRuntimeClasspath.txt
+++ b/app-thunderbird/dependencies/fossBetaRuntimeClasspath.txt
@@ -269,8 +269,8 @@ org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
-org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
-org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
+org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.0
+org.jetbrains.kotlinx:kotlinx-datetime:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
diff --git a/app-thunderbird/dependencies/fossDailyRuntimeClasspath.txt b/app-thunderbird/dependencies/fossDailyRuntimeClasspath.txt
index 3779b618d81..3d2667bc6af 100644
--- a/app-thunderbird/dependencies/fossDailyRuntimeClasspath.txt
+++ b/app-thunderbird/dependencies/fossDailyRuntimeClasspath.txt
@@ -269,8 +269,8 @@ org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
-org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
-org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
+org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.0
+org.jetbrains.kotlinx:kotlinx-datetime:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
diff --git a/app-thunderbird/dependencies/fossReleaseRuntimeClasspath.txt b/app-thunderbird/dependencies/fossReleaseRuntimeClasspath.txt
index 3779b618d81..3d2667bc6af 100644
--- a/app-thunderbird/dependencies/fossReleaseRuntimeClasspath.txt
+++ b/app-thunderbird/dependencies/fossReleaseRuntimeClasspath.txt
@@ -269,8 +269,8 @@ org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
-org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
-org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
+org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.0
+org.jetbrains.kotlinx:kotlinx-datetime:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
diff --git a/app-thunderbird/dependencies/fullBetaRuntimeClasspath.txt b/app-thunderbird/dependencies/fullBetaRuntimeClasspath.txt
index f94268c81d3..d0c664bbe71 100644
--- a/app-thunderbird/dependencies/fullBetaRuntimeClasspath.txt
+++ b/app-thunderbird/dependencies/fullBetaRuntimeClasspath.txt
@@ -283,8 +283,8 @@ org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
-org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
-org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
+org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.0
+org.jetbrains.kotlinx:kotlinx-datetime:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
diff --git a/app-thunderbird/dependencies/fullDailyRuntimeClasspath.txt b/app-thunderbird/dependencies/fullDailyRuntimeClasspath.txt
index f94268c81d3..d0c664bbe71 100644
--- a/app-thunderbird/dependencies/fullDailyRuntimeClasspath.txt
+++ b/app-thunderbird/dependencies/fullDailyRuntimeClasspath.txt
@@ -283,8 +283,8 @@ org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
-org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
-org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
+org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.0
+org.jetbrains.kotlinx:kotlinx-datetime:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
diff --git a/app-thunderbird/dependencies/fullReleaseRuntimeClasspath.txt b/app-thunderbird/dependencies/fullReleaseRuntimeClasspath.txt
index f94268c81d3..d0c664bbe71 100644
--- a/app-thunderbird/dependencies/fullReleaseRuntimeClasspath.txt
+++ b/app-thunderbird/dependencies/fullReleaseRuntimeClasspath.txt
@@ -283,8 +283,8 @@ org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
 org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
-org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
-org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
+org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.0
+org.jetbrains.kotlinx:kotlinx-datetime:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
 org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
diff --git a/core/android/common/src/main/kotlin/app/k9mail/core/android/common/contact/ContactKoinModule.kt b/core/android/common/src/main/kotlin/app/k9mail/core/android/common/contact/ContactKoinModule.kt
index df8c2e93abb..abcf1a0f15b 100644
--- a/core/android/common/src/main/kotlin/app/k9mail/core/android/common/contact/ContactKoinModule.kt
+++ b/core/android/common/src/main/kotlin/app/k9mail/core/android/common/contact/ContactKoinModule.kt
@@ -1,6 +1,7 @@
 package app.k9mail.core.android.common.contact

 import android.content.Context
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.common.cache.Cache
 import net.thunderbird.core.common.cache.ExpiringCache
 import net.thunderbird.core.common.cache.SynchronizedCache
@@ -10,6 +11,7 @@ import org.koin.dsl.module

 internal val contactModule = module {
     single<Cache<EmailAddress, Contact?>>(named(CACHE_NAME)) {
+        @OptIn(ExperimentalTime::class)
         SynchronizedCache(
             delegateCache = ExpiringCache(clock = get()),
         )
diff --git a/core/common/src/commonMain/kotlin/net/thunderbird/core/common/CoreCommonModule.kt b/core/common/src/commonMain/kotlin/net/thunderbird/core/common/CoreCommonModule.kt
index e2717ddc1e9..a85d7f83336 100644
--- a/core/common/src/commonMain/kotlin/net/thunderbird/core/common/CoreCommonModule.kt
+++ b/core/common/src/commonMain/kotlin/net/thunderbird/core/common/CoreCommonModule.kt
@@ -1,12 +1,14 @@
 package net.thunderbird.core.common

-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.common.oauth.InMemoryOAuthConfigurationProvider
 import net.thunderbird.core.common.oauth.OAuthConfigurationProvider
 import org.koin.core.module.Module
 import org.koin.dsl.module

 val coreCommonModule: Module = module {
+    @OptIn(ExperimentalTime::class)
     single<Clock> { Clock.System }

     single<OAuthConfigurationProvider> {
diff --git a/core/common/src/commonMain/kotlin/net/thunderbird/core/common/cache/ExpiringCache.kt b/core/common/src/commonMain/kotlin/net/thunderbird/core/common/cache/ExpiringCache.kt
index b60728744be..38dfd52619d 100644
--- a/core/common/src/commonMain/kotlin/net/thunderbird/core/common/cache/ExpiringCache.kt
+++ b/core/common/src/commonMain/kotlin/net/thunderbird/core/common/cache/ExpiringCache.kt
@@ -1,9 +1,12 @@
 package net.thunderbird.core.common.cache

-import kotlinx.datetime.Clock
-import kotlinx.datetime.Instant
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant

-class ExpiringCache<KEY : Any, VALUE : Any?>(
+class ExpiringCache<KEY : Any, VALUE : Any?>
+@OptIn(ExperimentalTime::class)
+constructor(
     private val clock: Clock,
     private val delegateCache: Cache<KEY, VALUE> = InMemoryCache(),
     private var lastClearTime: Instant = clock.now(),
@@ -26,6 +29,7 @@ class ExpiringCache<KEY : Any, VALUE : Any?>(
     }

     override fun clear() {
+        @OptIn(ExperimentalTime::class)
         lastClearTime = clock.now()
         delegateCache.clear()
     }
@@ -37,6 +41,7 @@ class ExpiringCache<KEY : Any, VALUE : Any?>(
     }

     private fun isExpired(): Boolean {
+        @OptIn(ExperimentalTime::class)
         return (clock.now() - lastClearTime).inWholeMilliseconds >= cacheTimeValidity
     }

diff --git a/core/logging/api/src/commonMain/kotlin/net/thunderbird/core/logging/DefaultLogger.kt b/core/logging/api/src/commonMain/kotlin/net/thunderbird/core/logging/DefaultLogger.kt
index 40561d92935..2a7f1eb9091 100644
--- a/core/logging/api/src/commonMain/kotlin/net/thunderbird/core/logging/DefaultLogger.kt
+++ b/core/logging/api/src/commonMain/kotlin/net/thunderbird/core/logging/DefaultLogger.kt
@@ -1,6 +1,7 @@
 package net.thunderbird.core.logging

-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime

 /**
  * Default implementation of [Logger] that logs messages to a [LogSink].
@@ -8,7 +9,9 @@ import kotlinx.datetime.Clock
  * @param sink The [LogSink] to which log events will be sent.
  * @param clock The [Clock] used to get the current time for log events. Defaults to the system clock.
  */
-class DefaultLogger(
+class DefaultLogger
+@OptIn(ExperimentalTime::class)
+constructor(
     private val sink: LogSink,
     private val clock: Clock = Clock.System,
 ) : Logger {
@@ -21,13 +24,15 @@ class DefaultLogger(
     ) {
         sink.let { currentSink ->
             if (currentSink.canLog(level)) {
+                @OptIn(ExperimentalTime::class)
+                val timestamp = clock.now().toEpochMilliseconds()
                 currentSink.log(
                     event = LogEvent(
                         level = level,
                         tag = tag,
                         message = message(),
                         throwable = throwable,
-                        timestamp = clock.now().toEpochMilliseconds(),
+                        timestamp = timestamp,
                     ),
                 )
             }
diff --git a/core/logging/impl-file/src/androidMain/kotlin/net/thunderbird/core/logging/file/AndroidFileLogSink.kt b/core/logging/impl-file/src/androidMain/kotlin/net/thunderbird/core/logging/file/AndroidFileLogSink.kt
index a0a157fee5f..954e2ff8018 100644
--- a/core/logging/impl-file/src/androidMain/kotlin/net/thunderbird/core/logging/file/AndroidFileLogSink.kt
+++ b/core/logging/impl-file/src/androidMain/kotlin/net/thunderbird/core/logging/file/AndroidFileLogSink.kt
@@ -5,13 +5,14 @@ import java.io.FileInputStream
 import java.io.FileOutputStream
 import java.io.IOException
 import kotlin.coroutines.CoroutineContext
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
-import kotlinx.datetime.Instant
 import kotlinx.datetime.LocalDateTime
 import kotlinx.datetime.TimeZone
 import kotlinx.datetime.toLocalDateTime
@@ -63,6 +64,7 @@ open class AndroidFileLogSink(
         }
     }

+    @OptIn(ExperimentalTime::class)
     private fun convertLongToTime(long: Long): String {
         val instant = Instant.fromEpochMilliseconds(long)
         val dateTime = instant.toLocalDateTime(TimeZone.currentSystemDefault())
diff --git a/feature/account/server/certificate/src/main/kotlin/app/k9mail/feature/account/server/certificate/domain/usecase/FormatServerCertificateError.kt b/feature/account/server/certificate/src/main/kotlin/app/k9mail/feature/account/server/certificate/domain/usecase/FormatServerCertificateError.kt
index de89a6b6a41..7274dccada4 100644
--- a/feature/account/server/certificate/src/main/kotlin/app/k9mail/feature/account/server/certificate/domain/usecase/FormatServerCertificateError.kt
+++ b/feature/account/server/certificate/src/main/kotlin/app/k9mail/feature/account/server/certificate/domain/usecase/FormatServerCertificateError.kt
@@ -7,12 +7,14 @@ import app.k9mail.feature.account.server.certificate.domain.entity.ServerCertifi
 import java.security.cert.X509Certificate
 import java.text.DateFormat
 import java.util.Date
-import kotlinx.datetime.Instant
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant
 import okio.ByteString
 import okio.HashingSink
 import okio.blackholeSink
 import okio.buffer

+@OptIn(ExperimentalTime::class)
 class FormatServerCertificateError(
     private val dateFormat: DateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT),
 ) : UseCase.FormatServerCertificateError {
diff --git a/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/FeatureFundingModule.kt b/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/FeatureFundingModule.kt
index cc0d7360ea6..a42ac6fbded 100644
--- a/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/FeatureFundingModule.kt
+++ b/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/FeatureFundingModule.kt
@@ -21,6 +21,7 @@ import app.k9mail.feature.funding.googleplay.ui.reminder.FundingReminder
 import app.k9mail.feature.funding.googleplay.ui.reminder.FundingReminderContract
 import app.k9mail.feature.funding.googleplay.ui.reminder.FundingReminderDialog
 import com.android.billingclient.api.ProductDetails
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.common.cache.Cache
 import net.thunderbird.core.common.cache.InMemoryCache
 import org.koin.core.module.dsl.viewModel
@@ -38,12 +39,14 @@ val featureFundingModule = module {
     }

     single<FundingReminderContract.ActivityLifecycleObserver> {
+        @OptIn(ExperimentalTime::class)
         ActivityLifecycleObserver(
             settings = get(),
         )
     }

     single<FundingReminderContract.Reminder> {
+        @OptIn(ExperimentalTime::class)
         FundingReminder(
             settings = get(),
             fragmentObserver = get(),
diff --git a/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/ActivityLifecycleObserver.kt b/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/ActivityLifecycleObserver.kt
index 8607731e394..bee4d62e96c 100644
--- a/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/ActivityLifecycleObserver.kt
+++ b/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/ActivityLifecycleObserver.kt
@@ -5,9 +5,12 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleObserver
 import androidx.lifecycle.LifecycleOwner
 import app.k9mail.feature.funding.api.FundingSettings
-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime

-class ActivityLifecycleObserver(
+class ActivityLifecycleObserver
+@OptIn(ExperimentalTime::class)
+constructor(
     private val settings: FundingSettings,
     private val clock: Clock = Clock.System,
 ) : FundingReminderContract.ActivityLifecycleObserver {
@@ -35,12 +38,14 @@ class ActivityLifecycleObserver(

             override fun onResume(owner: LifecycleOwner) {
                 super.onResume(owner)
+                @OptIn(ExperimentalTime::class)
                 startTime = clock.now().toEpochMilliseconds()
             }

             override fun onPause(owner: LifecycleOwner) {
                 super.onPause(owner)

+                @OptIn(ExperimentalTime::class)
                 val endTime = clock.now().toEpochMilliseconds()
                 val newActiveTime = endTime - startTime
                 val oldActiveTime = settings.getActivityCounterInMillis()
diff --git a/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/FundingReminder.kt b/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/FundingReminder.kt
index 2ea743c87d7..9581d3fa301 100644
--- a/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/FundingReminder.kt
+++ b/feature/funding/googleplay/src/main/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/FundingReminder.kt
@@ -7,9 +7,12 @@ import androidx.fragment.app.FragmentManager
 import app.k9mail.feature.funding.api.FundingSettings
 import app.k9mail.feature.funding.googleplay.ui.reminder.FundingReminderContract.ActivityLifecycleObserver
 import app.k9mail.feature.funding.googleplay.ui.reminder.FundingReminderContract.FragmentLifecycleObserver
-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime

-class FundingReminder(
+class FundingReminder
+@OptIn(ExperimentalTime::class)
+constructor(
     private val settings: FundingSettings,
     private val fragmentObserver: FragmentLifecycleObserver,
     private val activityCounterObserver: ActivityLifecycleObserver,
@@ -66,6 +69,7 @@ class FundingReminder(
     }

     private fun shouldShowReminder(): Boolean {
+        @OptIn(ExperimentalTime::class)
         val currentTime = clock.now().toEpochMilliseconds()

         return settings.getReminderShownTimestamp() == 0L &&
@@ -79,6 +83,7 @@ class FundingReminder(
             val installTime = context.packageManager.getPackageInfo(context.packageName, 0).firstInstallTime
             settings.setReminderReferenceTimestamp(installTime)
         } catch (exception: NameNotFoundException) {
+            @OptIn(ExperimentalTime::class)
             settings.setReminderReferenceTimestamp(clock.now().toEpochMilliseconds())
         }
     }
@@ -86,6 +91,7 @@ class FundingReminder(
     private fun showFundingReminderDialog(fragmentManager: FragmentManager) {
         // We're about to show the funding reminder dialog. So mark it as being shown. This way, if there's an error,
         // we err on the side of the dialog not being shown rather than it being shown more than once.
+        @OptIn(ExperimentalTime::class)
         settings.setReminderShownTimestamp(clock.now().toEpochMilliseconds())

         dialog.show(fragmentManager)
diff --git a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AppNotification.kt b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AppNotification.kt
index 887d0bf5bca..85b119853b8 100644
--- a/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AppNotification.kt
+++ b/feature/notification/api/src/commonMain/kotlin/net/thunderbird/feature/notification/api/content/AppNotification.kt
@@ -1,6 +1,7 @@
 package net.thunderbird.feature.notification.api.content

-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
 import kotlinx.datetime.LocalDateTime
 import kotlinx.datetime.TimeZone
 import kotlinx.datetime.toLocalDateTime
@@ -57,6 +58,8 @@ sealed interface Notification {
  */
 sealed class AppNotification : Notification {
     override val accessibilityText: String = title
+
+    @OptIn(ExperimentalTime::class)
     override val createdAt: LocalDateTime = Clock.System.now().toLocalDateTime(timeZone = TimeZone.UTC)
     override val actions: Set<NotificationAction> = emptySet()
     override val authenticationRequired: Boolean = false
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 0a70937fb81..e5651069071 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -81,7 +81,7 @@ kotlinGradleBom = "2.0.21"
 kotlinKsp = "2.1.21-2.0.2"
 kotlinxCoroutines = "1.10.2"
 kotlinxCollectionsImmutable = "0.4.0"
-kotlinxDateTime = "0.6.2"
+kotlinxDateTime = "0.7.0"
 kotlinxIoCore = "0.7.0"
 kotlinxSerialization = "1.8.1"
 ktlint = "1.5.0"
diff --git a/legacy/core/src/main/java/com/fsck/k9/QuietTimeChecker.kt b/legacy/core/src/main/java/com/fsck/k9/QuietTimeChecker.kt
index 5627e3ec72a..43e17c2dfea 100644
--- a/legacy/core/src/main/java/com/fsck/k9/QuietTimeChecker.kt
+++ b/legacy/core/src/main/java/com/fsck/k9/QuietTimeChecker.kt
@@ -1,10 +1,17 @@
 package com.fsck.k9

 import java.util.Calendar
-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime

 private const val MINUTES_PER_HOUR = 60
-class QuietTimeChecker(private val clock: Clock, quietTimeStart: String, quietTimeEnd: String) {
+class QuietTimeChecker
+@OptIn(ExperimentalTime::class)
+constructor(
+    private val clock: Clock,
+    quietTimeStart: String,
+    quietTimeEnd: String,
+) {
     private val quietTimeStart: Int = parseTime(quietTimeStart)
     private val quietTimeEnd: Int = parseTime(quietTimeEnd)

@@ -16,6 +23,7 @@ class QuietTimeChecker(private val clock: Clock, quietTimeStart: String, quietTi
             }

             val calendar = Calendar.getInstance()
+            @OptIn(ExperimentalTime::class)
             calendar.timeInMillis = clock.now().toEpochMilliseconds()

             val minutesSinceMidnight =
diff --git a/legacy/core/src/main/java/com/fsck/k9/job/KoinModule.kt b/legacy/core/src/main/java/com/fsck/k9/job/KoinModule.kt
index e238f2779b9..8378d7723ba 100644
--- a/legacy/core/src/main/java/com/fsck/k9/job/KoinModule.kt
+++ b/legacy/core/src/main/java/com/fsck/k9/job/KoinModule.kt
@@ -4,6 +4,7 @@ import android.content.Context
 import androidx.work.WorkManager
 import androidx.work.WorkerFactory
 import androidx.work.WorkerParameters
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.logging.Logger
 import org.koin.core.qualifier.named
 import org.koin.dsl.module
@@ -20,7 +21,12 @@ val jobModule = module {
         )
     }
     factory {
-        MailSyncWorkerManager(workManager = get(), clock = get(), syncDebugLogger = get<Logger>(named("syncDebug")))
+        @OptIn(ExperimentalTime::class)
+        MailSyncWorkerManager(
+            workManager = get(),
+            clock = get(),
+            syncDebugLogger = get<Logger>(named("syncDebug")),
+        )
     }
     factory { (parameters: WorkerParameters) ->
         MailSyncWorker(messagingController = get(), preferences = get(), context = get(), parameters)
diff --git a/legacy/core/src/main/java/com/fsck/k9/job/MailSyncWorkerManager.kt b/legacy/core/src/main/java/com/fsck/k9/job/MailSyncWorkerManager.kt
index 75dd645aad9..73c0253388d 100644
--- a/legacy/core/src/main/java/com/fsck/k9/job/MailSyncWorkerManager.kt
+++ b/legacy/core/src/main/java/com/fsck/k9/job/MailSyncWorkerManager.kt
@@ -9,12 +9,15 @@ import androidx.work.WorkManager
 import androidx.work.workDataOf
 import com.fsck.k9.K9
 import java.util.concurrent.TimeUnit
-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.android.account.LegacyAccount
 import net.thunderbird.core.logging.Logger
 import net.thunderbird.core.logging.legacy.Log

-class MailSyncWorkerManager(
+class MailSyncWorkerManager
+@OptIn(ExperimentalTime::class)
+constructor(
     private val workManager: WorkManager,
     val clock: Clock,
     val syncDebugLogger: Logger,
@@ -79,6 +82,7 @@ class MailSyncWorkerManager(
     }

     private fun calculateInitialDelay(lastSyncTime: Long, syncIntervalMinutes: Long): Long {
+        @OptIn(ExperimentalTime::class)
         val now = clock.now().toEpochMilliseconds()
         val nextSyncTime = lastSyncTime + (syncIntervalMinutes * 60L * 1000L)

diff --git a/legacy/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java b/legacy/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java
index ece8a4d5c74..da93913cc64 100644
--- a/legacy/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java
+++ b/legacy/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java
@@ -46,7 +46,7 @@
 import com.fsck.k9.mailstore.LockableDatabase.SchemaDefinition;
 import com.fsck.k9.message.extractors.AttachmentInfoExtractor;
 import net.thunderbird.feature.search.sql.SqlWhereClause;
-import kotlinx.datetime.Clock;
+import kotlin.time.Clock;
 import net.thunderbird.core.android.account.LegacyAccount;
 import net.thunderbird.feature.search.LocalMessageSearch;
 import net.thunderbird.feature.search.api.SearchAttribute;
diff --git a/legacy/core/src/main/java/com/fsck/k9/mailstore/OutboxStateRepository.kt b/legacy/core/src/main/java/com/fsck/k9/mailstore/OutboxStateRepository.kt
index b819854ad9e..a5075327886 100644
--- a/legacy/core/src/main/java/com/fsck/k9/mailstore/OutboxStateRepository.kt
+++ b/legacy/core/src/main/java/com/fsck/k9/mailstore/OutboxStateRepository.kt
@@ -5,9 +5,12 @@ import app.k9mail.core.android.common.database.getIntOrThrow
 import app.k9mail.core.android.common.database.getLongOrThrow
 import app.k9mail.core.android.common.database.getStringOrNull
 import app.k9mail.core.android.common.database.getStringOrThrow
-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime

-class OutboxStateRepository(
+class OutboxStateRepository
+@OptIn(ExperimentalTime::class)
+constructor(
     private val database: LockableDatabase,
     private val clock: Clock,
 ) {
@@ -79,6 +82,7 @@ class OutboxStateRepository(
     }

     fun setSendAttemptError(messageId: Long, errorMessage: String) {
+        @OptIn(ExperimentalTime::class)
         val sendErrorTimestamp = clock.now().toEpochMilliseconds()

         database.execute(false) { db ->
@@ -93,6 +97,7 @@ class OutboxStateRepository(
     }

     fun setSendAttemptsExceeded(messageId: Long) {
+        @OptIn(ExperimentalTime::class)
         val sendErrorTimestamp = clock.now().toEpochMilliseconds()

         database.execute(false) { db ->
diff --git a/legacy/core/src/main/java/com/fsck/k9/notification/CoreNotificationKoinModule.kt b/legacy/core/src/main/java/com/fsck/k9/notification/CoreNotificationKoinModule.kt
index d13f8ff1d9f..82b9857ddfa 100644
--- a/legacy/core/src/main/java/com/fsck/k9/notification/CoreNotificationKoinModule.kt
+++ b/legacy/core/src/main/java/com/fsck/k9/notification/CoreNotificationKoinModule.kt
@@ -4,6 +4,7 @@ import android.app.NotificationManager
 import android.content.Context
 import androidx.core.app.NotificationManagerCompat
 import java.util.concurrent.Executors
+import kotlin.time.ExperimentalTime
 import org.koin.dsl.module

 val coreNotificationModule = module {
@@ -71,6 +72,7 @@ val coreNotificationModule = module {
         )
     }
     single {
+        @OptIn(ExperimentalTime::class)
         NewMailNotificationManager(
             contentCreator = get(),
             notificationRepository = get(),
diff --git a/legacy/core/src/main/java/com/fsck/k9/notification/NewMailNotificationManager.kt b/legacy/core/src/main/java/com/fsck/k9/notification/NewMailNotificationManager.kt
index 17f934eb385..5514d24edc5 100644
--- a/legacy/core/src/main/java/com/fsck/k9/notification/NewMailNotificationManager.kt
+++ b/legacy/core/src/main/java/com/fsck/k9/notification/NewMailNotificationManager.kt
@@ -2,13 +2,16 @@ package com.fsck.k9.notification

 import app.k9mail.legacy.message.controller.MessageReference
 import com.fsck.k9.mailstore.LocalMessage
-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.android.account.LegacyAccount

 /**
  * Manages notifications for new messages
  */
-internal class NewMailNotificationManager(
+internal class NewMailNotificationManager
+@OptIn(ExperimentalTime::class)
+constructor(
     private val contentCreator: NotificationContentCreator,
     private val notificationRepository: NotificationRepository,
     private val baseNotificationDataCreator: BaseNotificationDataCreator,
@@ -134,5 +137,6 @@ internal class NewMailNotificationManager(
         }
     }

+    @OptIn(ExperimentalTime::class)
     private fun now(): Long = clock.now().toEpochMilliseconds()
 }
diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/AccountSettingsWriter.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/AccountSettingsWriter.kt
index 8ba1e6d63d1..7b2c1c561f1 100644
--- a/legacy/core/src/main/java/com/fsck/k9/preferences/AccountSettingsWriter.kt
+++ b/legacy/core/src/main/java/com/fsck/k9/preferences/AccountSettingsWriter.kt
@@ -5,7 +5,8 @@ import com.fsck.k9.Core
 import com.fsck.k9.Preferences
 import com.fsck.k9.mailstore.SpecialLocalFoldersCreator
 import java.util.UUID
-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.android.account.LegacyAccount
 import net.thunderbird.core.preference.storage.StorageEditor
 import net.thunderbird.feature.account.storage.legacy.LegacyAccountStorageHandler.Companion.ACCOUNT_DESCRIPTION_KEY
@@ -13,7 +14,9 @@ import net.thunderbird.feature.account.storage.legacy.LegacyAccountStorageHandle
 import net.thunderbird.feature.account.storage.legacy.LegacyAccountStorageHandler.Companion.OUTGOING_SERVER_SETTINGS_KEY
 import net.thunderbird.feature.account.storage.legacy.serializer.ServerSettingsDtoSerializer

-internal class AccountSettingsWriter(
+internal class AccountSettingsWriter
+@OptIn(ExperimentalTime::class)
+constructor(
     private val preferences: Preferences,
     private val localFoldersCreator: SpecialLocalFoldersCreator,
     private val clock: Clock,
@@ -50,6 +53,7 @@ internal class AccountSettingsWriter(
         // When deleting an account and then restoring it using settings import, the same account UUID will be used.
         // To avoid reusing a previously existing notification channel ID, we need to make sure to use a unique value
         // for `messagesNotificationChannelVersion`.
+        @OptIn(ExperimentalTime::class)
         val messageNotificationChannelVersion = clock.now().epochSeconds.toString()
         editor.putStringWithLogging(
             key = "$accountUuid.messagesNotificationChannelVersion",
diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt
index 27455af0fe1..0e268394ee9 100644
--- a/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt
+++ b/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt
@@ -1,6 +1,7 @@
 package com.fsck.k9.preferences

 import com.fsck.k9.Preferences
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.preference.DefaultPreferenceChangeBroker
 import net.thunderbird.core.preference.GeneralSettingsManager
 import net.thunderbird.core.preference.PreferenceChangeBroker
@@ -76,6 +77,7 @@ val preferencesModule = module {
     }

     factory {
+        @OptIn(ExperimentalTime::class)
         AccountSettingsWriter(
             preferences = get(),
             localFoldersCreator = get(),
diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/RealGeneralSettingsManager.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/RealGeneralSettingsManager.kt
index e1313f65287..604f5d2ee75 100644
--- a/legacy/core/src/main/java/com/fsck/k9/preferences/RealGeneralSettingsManager.kt
+++ b/legacy/core/src/main/java/com/fsck/k9/preferences/RealGeneralSettingsManager.kt
@@ -6,6 +6,8 @@ import app.k9mail.legacy.di.DI
 import com.fsck.k9.K9
 import com.fsck.k9.Preferences
 import com.fsck.k9.QuietTimeChecker
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -13,7 +15,6 @@ import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.launch
-import kotlinx.datetime.Clock
 import net.thunderbird.core.logging.legacy.Log
 import net.thunderbird.core.preference.AppTheme
 import net.thunderbird.core.preference.BackgroundSync
@@ -59,7 +60,6 @@ internal class RealGeneralSettingsManager(
 ) : GeneralSettingsManager, PrivacySettingsManager by privacySettingsManager {
     private val settingsFlow = MutableSharedFlow<GeneralSettings>(replay = 1)
     private var generalSettings: GeneralSettings? = null
-    val clock = DI.get<Clock>()

     @Deprecated("This only exists for collaboration with the K9 class")
     val storage: Storage
@@ -339,7 +339,13 @@ internal class RealGeneralSettingsManager(
         if (isQuietTimeEnabled) {
             return false
         }
-        val quietTimeChecker = QuietTimeChecker(clock, quietTimeStarts, quietTimeEnds)
+
+        @OptIn(ExperimentalTime::class)
+        val quietTimeChecker = QuietTimeChecker(
+            clock = DI.get<Clock>(),
+            quietTimeStart = quietTimeStarts,
+            quietTimeEnd = quietTimeEnds,
+        )
         return quietTimeChecker.isQuietTime
     }
 }
diff --git a/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatter.kt b/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatter.kt
index 14911766be4..dacd4857a21 100644
--- a/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatter.kt
+++ b/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatter.kt
@@ -12,18 +12,22 @@ import android.text.format.DateUtils.FORMAT_SHOW_YEAR
 import java.util.Calendar
 import java.util.Calendar.DAY_OF_WEEK
 import java.util.Calendar.YEAR
-import kotlinx.datetime.Clock
-import kotlinx.datetime.Instant
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant

 /**
  * Formatter to describe timestamps as a time relative to now.
  */
-class RelativeDateTimeFormatter(
+class RelativeDateTimeFormatter
+@OptIn(ExperimentalTime::class)
+constructor(
     private val context: Context,
     private val clock: Clock,
 ) {

     fun formatDate(timestamp: Long): String {
+        @OptIn(ExperimentalTime::class)
         val now = clock.now().toCalendar()
         val date = timestamp.toCalendar()
         val format = when {
@@ -42,6 +46,7 @@ private fun Long.toCalendar(): Calendar {
     return calendar
 }

+@OptIn(ExperimentalTime::class)
 private fun Instant.toCalendar(): Calendar {
     val calendar = Calendar.getInstance()
     calendar.timeInMillis = this.toEpochMilliseconds()
diff --git a/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt b/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt
index 03ce092fb17..97237f62079 100644
--- a/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt
+++ b/legacy/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt
@@ -63,12 +63,13 @@ import com.google.android.material.snackbar.BaseTransientBottomBar.BaseCallback
 import com.google.android.material.snackbar.Snackbar
 import com.google.android.material.textview.MaterialTextView
 import java.util.concurrent.Future
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.drop
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
-import kotlinx.datetime.Clock
 import net.jcip.annotations.GuardedBy
 import net.thunderbird.core.android.account.AccountManager
 import net.thunderbird.core.android.account.Expunge
@@ -107,6 +108,8 @@ class MessageListFragment :
     private val messagingController: MessagingController by inject()
     private val accountManager: AccountManager by inject()
     private val connectivityManager: ConnectivityManager by inject()
+
+    @OptIn(ExperimentalTime::class)
     private val clock: Clock by inject()
     private val setupArchiveFolderDialogFragmentFactory: SetupArchiveFolderDialogFragmentFactory by inject()
     private val legacyAccountWrapperDataMapper: DataMapper<
@@ -304,6 +307,7 @@ class MessageListFragment :
     }

     private fun createMessageListAdapter(): MessageListAdapter {
+        @OptIn(ExperimentalTime::class)
         return MessageListAdapter(
             theme = requireActivity().theme,
             res = resources,
diff --git a/legacy/ui/legacy/src/main/java/com/fsck/k9/view/KoinModule.kt b/legacy/ui/legacy/src/main/java/com/fsck/k9/view/KoinModule.kt
index bd9ef5f5961..6f34a2d0882 100644
--- a/legacy/ui/legacy/src/main/java/com/fsck/k9/view/KoinModule.kt
+++ b/legacy/ui/legacy/src/main/java/com/fsck/k9/view/KoinModule.kt
@@ -5,11 +5,15 @@ import com.fsck.k9.mailstore.AttachmentResolver
 import com.fsck.k9.message.ReplyActionStrategy
 import com.fsck.k9.ui.helper.RelativeDateTimeFormatter
 import com.fsck.k9.view.MessageWebView.OnPageFinishedListener
+import kotlin.time.ExperimentalTime
 import org.koin.dsl.module

 val viewModule = module {
     single { WebViewConfigProvider(themeManager = get(), generalSettingsManager = get()) }
-    factory { RelativeDateTimeFormatter(context = get(), clock = get()) }
+    factory {
+        @OptIn(ExperimentalTime::class)
+        RelativeDateTimeFormatter(context = get(), clock = get())
+    }
     factory { ReplyToParser() }
     factory { ReplyActionStrategy(replyRoParser = get()) }
     factory { (attachmentResolver: AttachmentResolver?, onPageFinishedListener: OnPageFinishedListener?) ->

diff --git a/core/common/src/commonTest/kotlin/net/thunderbird/core/common/cache/CacheTest.kt b/core/common/src/commonTest/kotlin/net/thunderbird/core/common/cache/CacheTest.kt
index 8409e3ce9ec..ff0ea54c86e 100644
--- a/core/common/src/commonTest/kotlin/net/thunderbird/core/common/cache/CacheTest.kt
+++ b/core/common/src/commonTest/kotlin/net/thunderbird/core/common/cache/CacheTest.kt
@@ -6,6 +6,7 @@ import assertk.assertions.isFalse
 import assertk.assertions.isNull
 import assertk.assertions.isTrue
 import kotlin.test.Test
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.testing.TestClock
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
@@ -28,7 +29,10 @@ class CacheTest(data: CacheTestData<Any, Any?>) {
         fun data(): Collection<CacheTestData<Any, Any?>> {
             return listOf(
                 CacheTestData("InMemoryCache") { InMemoryCache() },
-                CacheTestData("ExpiringCache") { ExpiringCache(TestClock(), InMemoryCache()) },
+                CacheTestData("ExpiringCache") {
+                    @OptIn(ExperimentalTime::class)
+                    ExpiringCache(TestClock(), InMemoryCache())
+                },
                 CacheTestData("SynchronizedCache") { SynchronizedCache(InMemoryCache()) },
             )
         }
diff --git a/core/common/src/commonTest/kotlin/net/thunderbird/core/common/cache/ExpiringCacheTest.kt b/core/common/src/commonTest/kotlin/net/thunderbird/core/common/cache/ExpiringCacheTest.kt
index 31aaab2332f..108a544db29 100644
--- a/core/common/src/commonTest/kotlin/net/thunderbird/core/common/cache/ExpiringCacheTest.kt
+++ b/core/common/src/commonTest/kotlin/net/thunderbird/core/common/cache/ExpiringCacheTest.kt
@@ -6,6 +6,7 @@ import assertk.assertions.isFalse
 import assertk.assertions.isNull
 import kotlin.test.Test
 import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.common.cache.Cache
 import net.thunderbird.core.common.cache.ExpiringCache
 import net.thunderbird.core.common.cache.InMemoryCache
@@ -13,8 +14,10 @@ import net.thunderbird.core.testing.TestClock

 class ExpiringCacheTest {

+    @OptIn(ExperimentalTime::class)
     private val clock = TestClock()

+    @OptIn(ExperimentalTime::class)
     private val testSubject: Cache<String, String> = ExpiringCache(clock, InMemoryCache())

     @Test
diff --git a/core/logging/api/src/commonTest/kotlin/net/thunderbird/core/logging/DefaultLoggerTest.kt b/core/logging/api/src/commonTest/kotlin/net/thunderbird/core/logging/DefaultLoggerTest.kt
index c84ffe38cfa..2f8d44f142e 100644
--- a/core/logging/api/src/commonTest/kotlin/net/thunderbird/core/logging/DefaultLoggerTest.kt
+++ b/core/logging/api/src/commonTest/kotlin/net/thunderbird/core/logging/DefaultLoggerTest.kt
@@ -5,9 +5,11 @@ import assertk.assertions.hasSize
 import assertk.assertions.isEqualTo
 import kotlin.test.Test
 import kotlin.time.Duration.Companion.milliseconds
-import kotlinx.datetime.Instant
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant
 import net.thunderbird.core.testing.TestClock

+@OptIn(ExperimentalTime::class)
 class DefaultLoggerTest {

     @Test
diff --git a/core/logging/impl-file/src/androidUnitTest/kotlin/net/thunderbird/core/logging/file/AndroidFileLogSinkTest.android.kt b/core/logging/impl-file/src/androidUnitTest/kotlin/net/thunderbird/core/logging/file/AndroidFileLogSinkTest.android.kt
index 7c17148d403..10449459f34 100644
--- a/core/logging/impl-file/src/androidUnitTest/kotlin/net/thunderbird/core/logging/file/AndroidFileLogSinkTest.android.kt
+++ b/core/logging/impl-file/src/androidUnitTest/kotlin/net/thunderbird/core/logging/file/AndroidFileLogSinkTest.android.kt
@@ -5,10 +5,11 @@ import assertk.assertions.isEqualTo
 import assertk.assertions.isNotNull
 import java.io.File
 import kotlin.test.Test
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.datetime.Instant
 import kotlinx.datetime.LocalDateTime
 import kotlinx.datetime.TimeZone
 import kotlinx.datetime.toLocalDateTime
@@ -44,6 +45,8 @@ class AndroidFileLogSinkTest {
             coroutineContext = UnconfinedTestDispatcher(),
         )
     }
+
+    @OptIn(ExperimentalTime::class)
     fun timeSetup(timeStamp: Long): String {
         val instant = Instant.fromEpochMilliseconds(timeStamp)
         val dateTime = instant.toLocalDateTime(TimeZone.currentSystemDefault())
diff --git a/core/testing/src/commonMain/kotlin/net/thunderbird/core/testing/TestClock.kt b/core/testing/src/commonMain/kotlin/net/thunderbird/core/testing/TestClock.kt
index 5acd77b0912..6ddb19ca19f 100644
--- a/core/testing/src/commonMain/kotlin/net/thunderbird/core/testing/TestClock.kt
+++ b/core/testing/src/commonMain/kotlin/net/thunderbird/core/testing/TestClock.kt
@@ -1,9 +1,11 @@
 package net.thunderbird.core.testing

+import kotlin.time.Clock
 import kotlin.time.Duration
-import kotlinx.datetime.Clock
-import kotlinx.datetime.Instant
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant

+@OptIn(ExperimentalTime::class)
 class TestClock(
     private var currentTime: Instant = Clock.System.now(),
 ) : Clock {
diff --git a/core/testing/src/commonTest/kotlin/net/thunderbird/core/testing/TestClockTest.kt b/core/testing/src/commonTest/kotlin/net/thunderbird/core/testing/TestClockTest.kt
index 4922c09eaa1..651ea477a3e 100644
--- a/core/testing/src/commonTest/kotlin/net/thunderbird/core/testing/TestClockTest.kt
+++ b/core/testing/src/commonTest/kotlin/net/thunderbird/core/testing/TestClockTest.kt
@@ -4,8 +4,10 @@ import assertk.assertThat
 import assertk.assertions.isEqualTo
 import kotlin.test.Test
 import kotlin.time.Duration.Companion.milliseconds
-import kotlinx.datetime.Instant
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant

+@OptIn(ExperimentalTime::class)
 internal class TestClockTest {

     @Test
diff --git a/feature/funding/googleplay/src/test/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/ActivityLifecycleObserverTest.kt b/feature/funding/googleplay/src/test/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/ActivityLifecycleObserverTest.kt
index 7382ea3f141..2f8583c423c 100644
--- a/feature/funding/googleplay/src/test/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/ActivityLifecycleObserverTest.kt
+++ b/feature/funding/googleplay/src/test/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/ActivityLifecycleObserverTest.kt
@@ -5,12 +5,14 @@ import androidx.lifecycle.testing.TestLifecycleOwner
 import assertk.assertThat
 import assertk.assertions.isEqualTo
 import kotlin.test.Test
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant
 import kotlinx.coroutines.test.runTest
-import kotlinx.datetime.Instant
 import net.thunderbird.core.testing.TestClock
 import net.thunderbird.core.testing.coroutines.MainDispatcherRule
 import org.junit.Rule

+@OptIn(ExperimentalTime::class)
 class ActivityLifecycleObserverTest {

     @get:Rule
diff --git a/feature/funding/googleplay/src/test/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/FundingReminderTest.kt b/feature/funding/googleplay/src/test/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/FundingReminderTest.kt
index 8c96b0c4a96..3a6bb1e4b39 100644
--- a/feature/funding/googleplay/src/test/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/FundingReminderTest.kt
+++ b/feature/funding/googleplay/src/test/kotlin/app/k9mail/feature/funding/googleplay/ui/reminder/FundingReminderTest.kt
@@ -14,13 +14,15 @@ import assertk.assertions.isEqualTo
 import assertk.assertions.isFalse
 import assertk.assertions.isTrue
 import kotlin.test.Test
-import kotlinx.datetime.Instant
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant
 import net.thunderbird.core.testing.TestClock
 import net.thunderbird.core.testing.coroutines.MainDispatcherRule
 import org.junit.Rule
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever

+@OptIn(ExperimentalTime::class)
 class FundingReminderTest {

     @get:Rule
diff --git a/legacy/core/src/test/java/com/fsck/k9/QuietTimeCheckerTest.kt b/legacy/core/src/test/java/com/fsck/k9/QuietTimeCheckerTest.kt
index 8a93a45d97c..a2c856ee0a8 100644
--- a/legacy/core/src/test/java/com/fsck/k9/QuietTimeCheckerTest.kt
+++ b/legacy/core/src/test/java/com/fsck/k9/QuietTimeCheckerTest.kt
@@ -4,10 +4,12 @@ import assertk.assertThat
 import assertk.assertions.isFalse
 import assertk.assertions.isTrue
 import java.util.Calendar
-import kotlinx.datetime.Instant
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant
 import net.thunderbird.core.testing.TestClock
 import org.junit.Test

+@OptIn(ExperimentalTime::class)
 class QuietTimeCheckerTest {
     private val clock = TestClock()

diff --git a/legacy/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt b/legacy/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt
index 294ec651e99..66fa5632bb4 100644
--- a/legacy/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt
+++ b/legacy/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt
@@ -18,7 +18,8 @@ import com.fsck.k9.mailstore.LocalStore
 import com.fsck.k9.mailstore.LocalStoreProvider
 import com.fsck.k9.mailstore.NotificationMessage
 import kotlin.test.assertNotNull
-import kotlinx.datetime.Instant
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant
 import net.thunderbird.core.android.account.LegacyAccount
 import net.thunderbird.core.preference.AppTheme
 import net.thunderbird.core.preference.BackgroundSync
@@ -38,6 +39,7 @@ private const val ACCOUNT_COLOR = 0xFF112233L.toInt()
 private const val FOLDER_ID = 42L
 private const val TIMESTAMP = 23L

+@OptIn(ExperimentalTime::class)
 class NewMailNotificationManagerTest {
     private val mockedNotificationMessages = mutableListOf<NotificationMessage>()
     private val account = createAccount()
diff --git a/legacy/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt b/legacy/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt
index 0588f75a633..40c1a3188bc 100644
--- a/legacy/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt
+++ b/legacy/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt
@@ -9,7 +9,8 @@ import assertk.assertions.isFalse
 import assertk.assertions.isInstanceOf
 import assertk.assertions.isTrue
 import com.fsck.k9.K9
-import kotlinx.datetime.Clock
+import kotlin.time.Clock
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.android.account.LegacyAccount
 import net.thunderbird.core.preference.AppTheme
 import net.thunderbird.core.preference.BackgroundSync
@@ -29,6 +30,7 @@ import org.mockito.kotlin.mock

 private val TIMESTAMP = 0L

+@OptIn(ExperimentalTime::class)
 class SummaryNotificationDataCreatorTest {
     private val account = createAccount()
     private var generalSettings = GeneralSettings(
diff --git a/legacy/ui/legacy/src/test/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatterTest.kt b/legacy/ui/legacy/src/test/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatterTest.kt
index ed7a7a89a80..1a6e970a2ea 100644
--- a/legacy/ui/legacy/src/test/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatterTest.kt
+++ b/legacy/ui/legacy/src/test/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatterTest.kt
@@ -8,7 +8,8 @@ import java.time.LocalDate
 import java.time.LocalDateTime
 import java.time.ZoneId
 import java.util.TimeZone
-import kotlinx.datetime.Instant
+import kotlin.time.ExperimentalTime
+import kotlin.time.Instant
 import net.thunderbird.core.android.testing.RobolectricTest
 import net.thunderbird.core.testing.TestClock
 import org.junit.Before
@@ -16,6 +17,7 @@ import org.junit.Test
 import org.robolectric.RuntimeEnvironment
 import org.robolectric.annotation.Config

+@OptIn(ExperimentalTime::class)
 @Config(
     qualifiers = "en",
     sdk = [Build.VERSION_CODES.S],
diff --git a/legacy/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt b/legacy/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt
index b60b330f2dd..dac4817955d 100644
--- a/legacy/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt
+++ b/legacy/ui/legacy/src/test/java/com/fsck/k9/ui/messagelist/MessageListAdapterTest.kt
@@ -24,6 +24,7 @@ import com.fsck.k9.mail.Address
 import com.fsck.k9.ui.R
 import com.fsck.k9.ui.helper.RelativeDateTimeFormatter
 import com.google.android.material.textview.MaterialTextView
+import kotlin.time.ExperimentalTime
 import net.thunderbird.core.android.account.LegacyAccount
 import net.thunderbird.core.android.testing.RobolectricTest
 import net.thunderbird.core.testing.TestClock
@@ -413,6 +414,7 @@ class MessageListAdapterTest : RobolectricTest() {
             density,
         )

+        @OptIn(ExperimentalTime::class)
         return MessageListAdapter(
             theme = context.theme,
             res = context.resources,