A constructive API enhancement.
Created JDK-8331202 <https://bugs.openjdk.org/browse/JDK-8331202> Support for duration between Instants

Regards, Roger

On 4/25/24 4:53 PM, Stephen Colebourne wrote:
java.time.* already has the `until(ChronoLocalDate)` method on
LocalDate. It would be reasonable to add a similar method to various
other classes. This potentially gives you

  Duration dur = start.until(end)

I'm wary of adding the opposite (given until() is already there). I'm
particularly wary of using minus() as the verb for the opposite as
minus() means something different in other parts of the API (minus()
is used to subtract a TemporalAmounrt, not a Temporal).

Stephen


On Thu, 25 Apr 2024 at 19:57, Kurt Alfred Kluever<k...@google.com>  wrote:
Hi core-libs-dev,

The java.time API already supports subtracting two Instants (end - start) via 
Duration.between(Temporal, Temporal), but we've found the parameter ordering (which 
requires a bit of "mental gymnastics") and API location to be a bit unnatural.

Parameter Ordering

We very often see folks write code like this: Duration elapsed = 
Duration.ofMillis(end.toEpochMilli() - start.toEpochMilli());

This closely matches the mental model of what they're trying to accomplish, but it is 
longer (and more complex) than it needs to be, it drops sub-millisecond precision, and it 
requires decomposing the java.time types (which we strongly discourage). If you want to 
"simplify" the above statement, you must remember to swap the argument order: 
Duration elapsed = Duration.between(start, end);

Many of us find representing (end - start) as between(start, end) to be 
confusing.

API Location

We do not believe Duration is the most obvious place to find this method; if 
you want a way to subtract two Instant values, an instance method on Instant is 
a more obvious place to look. Pushing what could be an instance method to a 
static utility method feels unnatural.

JDK-8276624 (https://bugs.openjdk.org/browse/JDK-8276624) proposes to add 
Temporal.minus(Temporal) as a default method (which would effectively 
accomplish the same thing), but we do not recommend implementing that proposal 
as specified. A default method on Temporal would require runtime exceptions to 
be thrown from other Temporal types like LocalDate or Year. It would also allow 
oddities like instant.minus(year) to compile (but presumably throw at runtime). 
Conceptually, this API would not make sense for certain types (e.g., LocalDate 
— the difference between two LocalDates is a Period, not a Duration).

Instead, we recommend adding a new instance method: instant.minus(instant) 
(which returns a Duration), and possibly also adding localDate.minus(localDate) 
(which returns a Period). However note that we've seen a lot of confusion using 
the Period API (but that's a separate discussion).

While we generally don't like having 2 public APIs that accomplish the same 
thing, in this case we feel the discoverability and simplicity of the new 
API(s) outweighs the cost of an additional public API.

Please consider this a +1 from our team to add instant.minus(instant).

Regards,

-Kurt Alfred Kluever (k...@google.com)
(on behalf of Google's Java and Kotlin Ecosystem Team, aka the Guava team)

Reply via email to