Proposal for new interface: TimeSource
Stephen Colebourne
scolebourne at joda.org
Thu May 6 23:27:41 UTC 2021
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