Search code examples
kotlinjava-timekotlinx

Can I get a fixed clock in kotlinx time?


I'm trying to transition my code to use kotlinx.datetime instead of the java.time library as I'd like to make use of the serialization benefits of the kotlinx library (it can serialize instant using the @Serialize annotation).

However, i have tests that are using the java.time.Clock and while there is a kotlinx.datetime.Clock class, it appears much more limited than the java one.

Is there a way I can achieve the same thing as this (which uses java.time.Clock and java.time.Instant):

val clockFixed = Clock.fixed(Instant.now().minusMillis(1000), ZONE_ID_UTC) 


using the kotlinx library? It doesn't have to be exactly like for like but I would like a clock that always returns the same instant so I can use it for tests and for production code.


Solution

  • kotlinx.datetime.Clock is a very simple interface that (as of version 0.4.0) only includes a single function declaration.

    /**
     * A source of [Instant] values.
     *
     * See [Clock.System][Clock.System] for the clock instance that queries the operating system.
     */
    public interface Clock {
        /**
         * Returns the [Instant] corresponding to the current time, according to this clock.
         */
        public fun now(): Instant
    
        ...
    }
    

    As of 0.4.0 there is no implementation of a Fixed clock provided by the library itself. However, you can easily provide your own implementation of a Fixed clock and make it available on the companion object of the Clock interface.

    public class FixedClock(private val fixedInstant: Instant): Clock {
        override fun now(): Instant = fixedInstant
    }
    
    private fun Clock.Companion.Fixed(fixedInstant: Instant): Clock = FixedClock(fixedInstant)
    

    Then, you can use it like the official System clock provided by the library.

    val systemClock: Clock = Clock.System
    val fixedClock: Clock = Clock.Fixed(...)