I've just started with calendar arithmetic, but I can already see how
tricky it is. Here are a few examples:
1. Existence of negative durations, which others mentioned in this thread.
2. There's the following asymmetry: while maximum duration is
Duration.ofSecond(Long.MAX_VALUE, 999_999_999), minimum duration is
Duration.ofSecond(Long.MIN_VALUE, 0).
3. There's also the fact that duration between any two instants is two
orders of magnitude smaller than maximum duration. That is,
var MAX = Duration.ofSeconds(Long.MAX_VALUE, 999_999_999);
var MAX_BETWEEN = Duration.between(Instant.MIN, Instant.MAX);
System.out.println(MAX.compareTo(MAX_BETWEEN));
System.out.println(MAX.dividedBy(MAX_BETWEEN));
outputs
1
146
(Kudos to Daniel Fuchs for this example.)
I get that people want to calculate deadlines. Given that the API is
hostile to overflows, calculating deadline from arbitrary values is
not right. Clients who want to robustly calculate a deadline given an
initial timestamp and a timeout should bite the bullet and use
something similar to this:
static Instant add(Instant i, Duration d) {
if (d.isNegative()) {
return Duration.between(i, Instant.MIN).compareTo(d) >= 0
? Instant.MIN : i.plus(d);
} else {
return Duration.between(i, Instant.MAX).compareTo(d) <= 0
? Instant.MAX : i.plus(d);
}
}
(I won't be surprised if that snippet has bugs.)
On Thu, Sep 4, 2025 at 10:33 PM Stephen Colebourne <[email protected]> wrote:
>
> The best reason for adding MAX (max positive) and MIN (max negative)
> is that the alternative is digging around in the Javadoc to figure it
> out, and probably getting it wrong. It also provides a great place to
> document the usage issues, which are no different to Long.MAX_VALUE or
> Instant.MAX. Which is the bigger point here - MAX/MIN values are
> *always* weird, and I really wouldn't overthink this.
>
> I understand the appeal of a BIG value, but it is a domain specific
> thing and not for the JDK in my view.
>
> Stephen
>
>
> On Thu, 4 Sept 2025 at 02:33, Roger Riggs <[email protected]> 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 <[email protected]> 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 <[email protected]> im Auftrag von Pavel
> >> Rappo <[email protected]>
> >> Gesendet: Donnerstag, September 4, 2025 12:41 AM
> >> An: Kurt Alfred Kluever <[email protected]>
> >> Cc: Stephen Colebourne <[email protected]>; core-libs-dev
> >> <[email protected]>
> >> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]>
> >> >> wrote:
> >> >> >
> >> >> > On Wed, Sep 3, 2025 at 6:06 PM Stephen Colebourne
> >> >> > <[email protected]> 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
> >
> >