Proposal for new interface: TimeSource

Aaron Scott-Boddendijk talden at gmail.com
Mon May 10 05:06:36 UTC 2021


Yes please.

I often have people ask how they should solve exactly this problem and we
have several code-bases that have their own implementations of essentially
this interface.

We've used it not only for the request-contextual time localisation but for
controlling the stepping for data-processing and simulation.

A standard interface might also mean this makes its way into 1st-class
testing framework parameterisation.

--
Aaron Scott-Boddendijk


On Fri, May 7, 2021 at 11:28 AM Stephen Colebourne <scolebourne at joda.org>
wrote:

> This is a proposal to add a new interface to java.time.*
>
>   public interface TimeSource {
>     public static TimeSource system() { ... }
>     public abstract Instant instant();
>     public default long millis() {
>       return instant().toEpochMilli();
>     }
>     public default Clock withZone(ZoneId zoneId) {
>       return Clock.of(this, zoneId);
>    }
>   }
>
> The existing `Clock` abstract class would be altered to implement the
> interface.
> A new static method `Clock.of(TimeSource, ZoneId)` would be added.
> No changes are needed to any other part of the API.
> (Could add `Instant.now(TimeSource)`, but it isn't entirely necessary)
>
> Callers would pass around and use `TimeSource` directly, for example
> by dependency injection.
>
>
> Why add this interface?
> I've seen various indications that there is a desire for an interface
> representing a supplier of `Instant`. Specifically this desire is
> driven by the "unnecessary" time zone that `java.time.Clock` contains.
> Put simply, if the only thing you want is an `Instant`, then `Clock`
> isn't the right API because it forces you to think about time zones.
>
> A key thing that this interface allows is the separation of the OS
> Clock from the time-zone (which should generally be linked to user
> localization). A good architecture would pass `TimeSource` around the
> system and combine it with a time-zone held in a `UserContext` to get
> a `Clock`. The current design of java.time.* does not enable that
> because the `TimeSource` concept does not exist. Developers either
> have to write their own interface, or use `Clock` and ignore the time
> zone.
>
> A `Supplier<Instant>` obviously performs similar functionality, but it
> lacks discoverability and understandability. Plus, injecting
> generified interfaces tends to be painful.
>
> Downsides?
> None really, other than a new type in the JDK that probably should
> have been in Java 8.
>
>
> See this ThreeTen-Extra discussion
> - https://github.com/ThreeTen/threeten-extra/issues/150
>
> Joda-Time has a `MillisProvider` that is similar:
> -
> https://www.joda.org/joda-time/apidocs/org/joda/time/DateTimeUtils.MillisProvider.html
>
> Time4J has a `TimeSource`:
> -
> https://github.com/MenoData/Time4J/blob/master/base/src/main/java/net/time4j/base/TimeSource.java
>
> Spring has a `DateTimeContext` that separates the user localization as
> per the `UserContext` described above:
> -
> https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/format/datetime/standard/DateTimeContext.html
>
> There is a similar concept `TimeSource` in `sun.net.httpserver`
>
> There may be a case to name the interface `InstantSource`, however
> `TimeSource` is a fairly widely understood name for this concept.
>
>
> There is the potential to extend the interface with something similar
> to Kotlin's `TimeMark` that would allow access to the monotonic clock,
> suitable for measurement of durations without any leap second effects:
> - https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.time/-time-mark/
>
> Feedback?
>
> Stephen
>


More information about the core-libs-dev mailing list