Duration.MAX_VALUE

Éamonn McManus emcmanus at google.com
Thu Sep 4 22:02:19 UTC 2025


Two typical use cases:

// 1. Sentinel
Duration min = Duration.MAX;
for (var foo : something()) {
  if (foo.duration().compareTo(min) < 0) {
    min = foo.duration();
  }
}

// 2. "Forever"
void frob(Optional<Duration> optionalTimeout) {
  Duration timeout = optionalTimeout.orElse(Duration.MAX);
  Instant start = Instant.now();
  boolean done = false;
  while (!done && startTime.until(Instant.now()).compareTo(timeout) < 0)
{...}
}

The second case illustrates why this is potentially a bit delicate. You
better not write this:

void frob(Optional<Duration> optionalTimeout) {
  Duration timeout = optionalTimeout.orElse(Duration.MAX);
  Instant deadline = Instant.now().plus(timeout); // oops
  boolean done = false;
  while (!done && Instant.now().isBefore(deadline)) {...}
}

Like Kevin, I am skeptical about Duration.MIN. If it means the most
negative Duration, that is just Duration.MAX.negated(); and if it means the
smallest positive Duration, that is just Duration.ofNanos(1).

On Wed, 3 Sept 2025 at 18:32, Roger Riggs <roger.riggs at oracle.com> wrote:

> Hi,
>
> I'd be interested in the range of use cases for Duration.MAX or MIN.
>
> But for deadlines, I think the code should compute the deadline from a
> Duration of its choice based on the use.
> Maybe there is a use for Duration.REALLY_BIG or _SMALL, but that ignores
> information about the particular use that is relevant. Its just sloppy code
> that doesn't bother to express how long is long enough to meet operational
> parameters.
>
> YMMV, Roger
>
> On 9/3/25 8:21 PM, Kurt Alfred Kluever wrote:
>
> Duration.MIN is a whole 'nother bag of worms, because Durations are signed
> (they can be positive or negative...or zero). Internally we also have
> Durations.MIN, but it's not public ... and along with it, I left myself a
> helpful note about naming:
>
>   /** The minimum supported {@code Duration}, approximately -292 billion
> years. */
>   // Note: before making this constant public, consider that "MIN" might
> not be a great name (not
>   //       everyone knows that Durations can be negative!).
>   static final Duration MIN = Duration.ofSeconds(Long.MIN_VALUE);
>
> This reminds me of Double.MIN_VALUE (which is the smallest _positive_
> double value) --- we've seen Double.MIN_VALUE misused so much that we
> introduced Doubles.MIN_POSITIVE_VALUE as a more descriptive alias. A large
> percent of Double.MIN_VALUE users actually want the smallest possible
> negative value, aka -Double.MAX_VALUE.
>
> If we introduce Duration.MIN, I hope it would not be Duration.ofNanos(1),
> but rather Duration.ofSeconds(Long.MIN_VALUE).
>
> On Wed, Sep 3, 2025 at 7:59 PM ecki <ecki at zusammenkunft.net> wrote:
>
>> If you ask me, I don’t find it very useful, It won’t work for
>> arithmetrics, even the APIs would have a hard time using it (how do you
>> express the deadline) and APIs with a timeout parameter do have a good
>> reason for it, better pick “possible” values for better self healing and
>> unstuck of systems. In fact I would err on the smaller side in combination
>> with expecting spurious wakeups.
>>
>> BTW, when you introduce MIN as well, maybe also think about min
>> precision, min delta or such. Will it always be 1 nano?
>>
>> Gruß,
>> Bernd
>> --
>> https://bernd.eckenfels.net
>> ------------------------------
>> *Von:* core-libs-dev <core-libs-dev-retn at openjdk.org> im Auftrag von
>> Pavel Rappo <pavel.rappo at gmail.com>
>> *Gesendet:* Donnerstag, September 4, 2025 12:41 AM
>> *An:* Kurt Alfred Kluever <kak at google.com>
>> *Cc:* Stephen Colebourne <scolebourne at joda.org>; core-libs-dev <
>> core-libs-dev at openjdk.org>
>> *Betreff:* Re: Duration.MAX_VALUE
>>
>> This is useful; thanks. It would be good to see more of your data.
>>
>> My use case is also duration which practically means **forever**. I
>> pass it to methods that accept timeouts, and expect these methods to
>> correctly interpret it.
>>
>> One example of a practical interpretation is
>> java.util.concurrent.TimeUnit.convert(Duration). This method never
>> overflows; instead, it caps at Long.MAX_VALUE nanoseconds, which is
>> roughly 292 years.
>>
>> Would I be okay, if the proposed duration didn't reflect **forever**
>> but instead reflected **long enough**? I think so. But it still
>> somehow feels wrong to make it less than maximum representable value.
>>
>> Personally, I'm not interested in calendar arithmetic, that is, in
>> adding or subtracting durations. Others might be, and that's okay and
>> needs to be factored in. For better or worse, java.time made a choice
>> to be unforgiving in regard to overflow and is very upfront about it.
>> It's not only proposed Duration.MAX. The same thing happens if you try
>> this
>>
>> Instant.MAX.toEpochMilli()
>>
>> I guess my point is that doing calendar arithmetic on an unknown value
>> is probably wrong. Doing it on a known huge/edge-case value is surely
>> wrong. So back to your data. I would be interested to see what
>> triggers overflows for your Durations.MAX.
>>
>> On Wed, Sep 3, 2025 at 8:45 PM Kurt Alfred Kluever <kak at google.com>
>> wrote:
>> >
>> > Hi all,
>> >
>> > Internally at Google, we've had a Durations.MAX constant exposed for
>> the past 7 years. It now has about 700 usages across our depot, which I can
>> try to categorize (at a future date).
>> >
>> > While I haven't performed that analysis yet, I think exposing this
>> constant was a bit of a mistake. People seem to want to use MAX to mean
>> "forever" (often in regards to an RPC deadline). This works fine as long as
>> every single layer that touches the deadline is very careful about
>> overflow. The only reasonable thing you can do with MAX is compareTo() and
>> equals(). Attempting to do any simple math operation (e.g., now+deadline)
>> is going to explode. Additionally, decomposing Duration.MAX explodes for
>> any sub-second precision (e.g., toMillis()).
>> >
>> > As we dug into this, another proposal came up which was something like
>> Durations.VERY_LONG. This duration would be longer than any reasonable
>> finite duration but not long enough to cause an overflow when added to any
>> reasonable time. E.g., a million years would probably satisfy both
>> criteria. This would mean math operations and decompositions won't explode
>> (well, microseconds and nanoseconds still would), and it could safely be
>> used as a relative timeout.
>> >
>> > As I mentioned above, I'd be happy to try to categorize a sample of our
>> 700 existing usages if folks think that would be useful for this proposal.
>> >
>> > Thanks,
>> >
>> > -Kurt Alfred Kluever (on behalf of Google's Java and Kotlin Ecosystem
>> team)
>> >
>> > On Wed, Sep 3, 2025 at 1:53 PM Pavel Rappo <pavel.rappo at gmail.com>
>> wrote:
>> >>
>> >> If I understood you correctly, you think we should also add
>> >> Duration.MIN. If so, what use case do you envision for it? Or we add
>> >> if purely for symmetry with Instant?
>> >>
>> >> On Wed, Sep 3, 2025 at 6:43 PM Pavel Rappo <pavel.rappo at gmail.com>
>> wrote:
>> >> >
>> >> > On Wed, Sep 3, 2025 at 6:06 PM Stephen Colebourne <
>> scolebourne at joda.org> wrote:
>> >> > >
>> >> > > Hmm, yes. Not sure why that didn't get added in Java 8!
>> >> > > The constants would be MAX/MIN as per classes like Instant.
>> >> > > Stephen
>> >> >
>> >> > I thought that naming could be tricky :) The public constant
>> >> > Duration.ZERO and the public method isZero() are already there.
>> >> > However, it does not preclude us from naming a new constant MAX.
>> >
>> >
>> >
>> > --
>> > kak
>>
>>
>
> --
> kak
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20250904/59f8d281/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5281 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20250904/59f8d281/smime-0001.p7s>


More information about the core-libs-dev mailing list