Duration.MAX_VALUE

Pavel Rappo pavel.rappo at gmail.com
Tue Sep 23 19:43:31 UTC 2025


This thread has stalled. Let me summarise my current understanding of
where we are.

These are the use cases for Duration.MAX that we have identified:

  * an algorithm sentinel,
  * edge-case testing,
  * an infinite timeout.

Let's quickly deal with the first two. On the one hand, you don't need
a sentinel if your algorithm can be expressed as a stream; streams
have Optional. On the other hand, manually constructing Duration.MAX
for edge case testing (or anything else for that matter) is
error-prone. So it seems that having Duration.MAX is a net benefit for
the first two use cases.

Now let's talk about timeouts, the most controversial of the use
cases. There are a couple of options to handle a timeout:

* delegate,
* do it yourself,
* use a combination of the above.

If the timeout is a big (but not necessarily maximum) Duration, every
option above has hazards. If you delegate a timeout, you rely on the
delegate to handle it normally. An example of such a delegate is
Thread.join or Process.waitFor. An example of an opposite delegate is
HttpClient.Builder.connectTimeout; if passed with a sufficiently big
Duration, an exception will be thrown when you try to send a request.

If you handle a timeout yourself, you can compute the deadline once
and then track the current time. Alternatively, you can subtract the
elapsed time from the timeout as you go, and track that remaining
timeout. In any case, you should be prepared for overflow.

You may also want to use a combination of the above. In a compound
scenario, you track part of the timeout, and delegate the rest of it.
In this case you rely on your delegate(s) and must also be prepared
for overflow.

**A note on delegation.** Some APIs use special values to indicate an
infinite timeout. For example, Object.wait(long) and
Socket.setSoTimeout(int) use 0. Also, some APIs only track small
timeouts. For example, since Socket.setSoTimeout(int) is in
milliseconds, everything longer than 24 days is an infinite timeout. A
higher-level API that accepts Duration will need to decide how to
handle a longer timeout if it uses Socket.

How to generally handle an infinite timeout? In an API you can:

- Add a method that takes Optional<Duration>. One issue here is that
IIRC an Optional argument is frowned upon. Another issue is that such
a method would only look reasonable if there isn't already a method
that takes Duration. If there is, it could confuse a user.

- Along with an existing method that takes Duration, add a method that
doesn't take it. One issue is that it precludes API from using such a
method to mean _default_ Duration, which might not necessarily be
infinite.

Separately, the following can be added to java.time:

- The Duration.MAX constant such that there's no Duration greater than
it. The issue is that if passed to naive code, it might -- and will
likely -- overflow.

- A Duration constant, big enough to mean infinite, but small enough
to not cause overflow in the vast majority of practical cases --
maximum safe Duration. The issue is that we'll be guessing the value
for all the ways a timeout can be computed. This includes, for
example, figuring out a reasonable maximum Instant, to which we can
safely add such a constant. In other words, this option has unknowns.

- A set of method that adds Duration to Instant or subtracts Duration
from Duration with saturation/cap. These methods can be used by a 3rd
party client to implement typical, correct and efficient deadline and
timeout calculation.

-----

As a conclusion, I'm not sure what the benefit of getting
ArithmeticException is when performing timeout-related arithmetic on
Duration and Instant. I think that adding Duration.MAX as well as
saturating arithmetic methods to Duration and Instant could be good.
If we add those, then the API design (discussed above) becomes an
orthogonal concern.

Note that whatever the API design you choose (a single
Optional<Duration> method or a pair of methods, one with Duration and
one without), without special treatment you are still exposed to
overflows for sufficiently big Duration or Instant.

On Wed, Sep 3, 2025 at 12:49 PM Pavel Rappo <pavel.rappo at gmail.com> wrote:
>
> Couldn't recall or quickly find if this was asked before.
>
> I come across this quite often: there doesn’t seem to be a readily
> available maximum value for java.time.Duration -- a value that
> represents the longest possible duration.
>
> I assume there are plenty of homegrown constants out in the wild
> addressing this. Don’t get me wrong: it’s not hard to create one. The
> issue, in my experience, is that it takes time and sometimes
> experimentation.
>
> Unless one reads the Javadoc carefully, it’s not obvious that the
> maximum duration can be constructed as follows:
>
>     Duration.of(Long.MAX_VALUE, 999_999_999);
>
> Naturally, one might first try using IDE autocomplete. For example,
> creating a Duration from Long.MAX_VALUE of a large unit -- millennia,
> centuries, decades, etc. -- only to run into ArithmeticException. Only
> when reaching seconds does it finally work:
>
>     Duration.ofSeconds(Long.MAX_VALUE);
>
> or
>
>     Duration.of(Long.MAX_VALUE, ChronoUnit.SECONDS);
>
> Of course, there’s no practical difference between
> Duration.of(Long.MAX_VALUE, 999_999_999) and
> Duration.ofSeconds(Long.MAX_VALUE). We’re talking about durations on
> the order of 292 billion years, after all. The exact value isn’t the
> problem. The problem is that the values are inconsistent, and arriving
> to them is error-prone. Adding a constant to java.time.Duration would
> simplify things.
>
> -Pavel


More information about the core-libs-dev mailing list