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