In support of Instant.minus(Instant)
Kurt Alfred Kluever
kak at google.com
Thu May 2 14:57:54 UTC 2024
Hi all,
Thanks for filing JDK-8331202 (https://bugs.openjdk.org/browse/JDK-8331202).
I think this proposal is definitely a step in the right direction. The
Instant instance method is much more discoverable than the Duration static
method. I also think there's a much lower chance of users accidentally
swapping the arguments.
However, I still have concerns about the method name (and thus indirectly
the ordering of the arguments). Users are very accustomed to performing
this calculation with primitives as (end - start). This is a basic, common,
familiar way of thinking about this operation (especially with primitives),
and it's a good idea to lean into that familiarity. I understand there's
some precedent for until() (thanks for pointing this out, Stephen!), but I
think it requires too much "mental gymnastics" to translate from conceptual
model to Actual Code.
Kevin Bourillion has written a great programming guide called "How to Think
About Time" (internal to Google for now, but we hope to publish it sometime
later this year). One section enumerates the available math operations for
the time types:
- instant − instant = duration // what we're discussing
- instant + duration = instant // satisfied by instant.plus(duration)
- instant - duration = instant // satisfied by instant.minus(duration)
- duration + duration = duration // satisfied by duration.plus(duration)
- duration - duration = duration // satisfied by duration.minus(duration)
- duration × real number = duration // satisfied by
duration.multipliedBy(long)
- duration ÷ real number = duration // satisfied by
duration.dividedBy(long)
All but the first operation have very clear translations from conceptual
model to code. I'm hoping we can achieve the same clarity for instant -
instant by using the obvious name: instant.minus(instant)
Thanks!
-Kurt Alfred Kluever
On Fri, Apr 26, 2024 at 11:07 AM Roger Riggs <roger.riggs at oracle.com> wrote:
> 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 <kak at google.com> <kak at 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 (kak at google.com)
> (on behalf of Google's Java and Kotlin Ecosystem Team, aka the Guava team)
>
>
>
--
kak
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240502/a4e56de9/attachment.htm>
More information about the core-libs-dev
mailing list