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 <[email protected]> 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
