<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Aptos;
        panose-1:2 11 0 4 2 2 2 2 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:10.0pt;
        font-family:"Aptos",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Aptos",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        mso-ligatures:none;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:81072519;
        mso-list-type:hybrid;
        mso-list-template-ids:-1258276754 108558620 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l0:level1
        {mso-level-start-at:25;
        mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:11.0pt;
        font-family:Wingdings;
        mso-fareast-font-family:"Times New Roman";
        mso-bidi-font-family:Aptos;}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l0:level3
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l0:level4
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;}
@list l0:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l0:level6
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l0:level7
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;}
@list l0:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l0:level9
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l1
        {mso-list-id:727267522;
        mso-list-type:hybrid;
        mso-list-template-ids:-1626832628 1738829534 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l1:level1
        {mso-level-start-at:25;
        mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:11.0pt;
        font-family:Wingdings;
        mso-fareast-font-family:"Times New Roman";
        mso-bidi-font-family:Aptos;}
@list l1:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l1:level3
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l1:level4
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;}
@list l1:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l1:level6
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l1:level7
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;}
@list l1:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l1:level9
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;}
ol
        {margin-bottom:0in;}
ul
        {margin-bottom:0in;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt">From the peanut gallery, in case it is helpful.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">> MAX/MIN values are *always* weird, and I really wouldn't overthink this.</span><span style="font-size:12.0pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Well, if Kurt’s willing to analyze a sample of those 700 usages to understand what they’re really trying to do, I think we can have a smarter discussion with that info in hand, and this wouldn’t seem like
 overthinking to me.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">And… I’m not sure why we started talking about MIN in the same breath. It didn’t seem to be motivated by use cases or arguments of real-world  benefit, and imho, symmetry alone shouldn’t suffice as justification.
 Plus I have a particular concern; I think <i>many</i> users have never quite realized that durations can be negative, and will misunderstand what `MIN` is when they see it. We might make the exact inverse mistake as with Double.MIN_VALUE…<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<div id="mail-editor-reference-message-container">
<div>
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">core-libs-dev <core-libs-dev-retn@openjdk.org> on behalf of Stephen Colebourne <scolebourne@joda.org><br>
<b>Date: </b>Thursday, September 4, 2025 at 2:33</span><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:black"> </span><span style="font-size:12.0pt;color:black">PM<br>
<b>To: </b>core-libs-dev@openjdk.org <core-libs-dev@openjdk.org><br>
<b>Subject: </b>Re: Duration.MAX_VALUE<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">The best reason for adding MAX (max positive) and MIN (max negative)<br>
is that the alternative is digging around in the Javadoc to figure it<br>
out, and probably getting it wrong. It also provides a great place to<br>
document the usage issues, which are no different to Long.MAX_VALUE or<br>
Instant.MAX. Which is the bigger point here - MAX/MIN values are<br>
*always* weird, and I really wouldn't overthink this.<br>
<br>
I understand the appeal of a BIG value, but it is a domain specific<br>
thing and not for the JDK in my view.<br>
<br>
Stephen<br>
<br>
<br>
On Thu, 4 Sept 2025 at 02:33, Roger Riggs <roger.riggs@oracle.com> wrote:<br>
><br>
> Hi,<br>
><br>
> I'd be interested in the range of use cases for Duration.MAX or MIN.<br>
><br>
> But for deadlines, I think the code should compute the deadline from a Duration of its choice based on the use.<br>
> 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.<br>
><br>
> YMMV, Roger<br>
><br>
> On 9/3/25 8:21 PM, Kurt Alfred Kluever wrote:<br>
><br>
> 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:<br>
><br>
>   /** The minimum supported {@code Duration}, approximately -292 billion years. */<br>
>   // Note: before making this constant public, consider that "MIN" might not be a great name (not<br>
>   //       everyone knows that Durations can be negative!).<br>
>   static final Duration MIN = Duration.ofSeconds(Long.MIN_VALUE);<br>
><br>
> 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.<br>
><br>
> If we introduce Duration.MIN, I hope it would not be Duration.ofNanos(1), but rather Duration.ofSeconds(Long.MIN_VALUE).<br>
><br>
> On Wed, Sep 3, 2025 at 7:59</span><span style="font-size:11.0pt;font-family:"Arial",sans-serif"> </span><span style="font-size:11.0pt">PM ecki <ecki@zusammenkunft.net> wrote:<br>
>><br>
>> 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.<br>
>><br>
>> BTW, when you introduce MIN as well, maybe also think about min precision, min delta or such. Will it always be 1 nano?<br>
>><br>
>> Gruß,<br>
>> Bernd<br>
>> --<br>
>> <a href="https://bernd.eckenfels.net">https://bernd.eckenfels.net</a><br>
>> ________________________________<br>
>> Von: core-libs-dev <core-libs-dev-retn@openjdk.org> im Auftrag von Pavel Rappo <pavel.rappo@gmail.com><br>
>> Gesendet: Donnerstag, September 4, 2025 12:41 AM<br>
>> An: Kurt Alfred Kluever <kak@google.com><br>
>> Cc: Stephen Colebourne <scolebourne@joda.org>; core-libs-dev <core-libs-dev@openjdk.org><br>
>> Betreff: Re: Duration.MAX_VALUE<br>
>><br>
>> This is useful; thanks. It would be good to see more of your data.<br>
>><br>
>> My use case is also duration which practically means **forever**. I<br>
>> pass it to methods that accept timeouts, and expect these methods to<br>
>> correctly interpret it.<br>
>><br>
>> One example of a practical interpretation is<br>
>> java.util.concurrent.TimeUnit.convert(Duration). This method never<br>
>> overflows; instead, it caps at Long.MAX_VALUE nanoseconds, which is<br>
>> roughly 292 years.<br>
>><br>
>> Would I be okay, if the proposed duration didn't reflect **forever**<br>
>> but instead reflected **long enough**? I think so. But it still<br>
>> somehow feels wrong to make it less than maximum representable value.<br>
>><br>
>> Personally, I'm not interested in calendar arithmetic, that is, in<br>
>> adding or subtracting durations. Others might be, and that's okay and<br>
>> needs to be factored in. For better or worse, java.time made a choice<br>
>> to be unforgiving in regard to overflow and is very upfront about it.<br>
>> It's not only proposed Duration.MAX. The same thing happens if you try<br>
>> this<br>
>><br>
>> Instant.MAX.toEpochMilli()<br>
>><br>
>> I guess my point is that doing calendar arithmetic on an unknown value<br>
>> is probably wrong. Doing it on a known huge/edge-case value is surely<br>
>> wrong. So back to your data. I would be interested to see what<br>
>> triggers overflows for your Durations.MAX.<br>
>><br>
>> On Wed, Sep 3, 2025 at 8:45</span><span style="font-size:11.0pt;font-family:"Arial",sans-serif"> </span><span style="font-size:11.0pt">PM Kurt Alfred Kluever <kak@google.com> wrote:<br>
>> ><br>
>> > Hi all,<br>
>> ><br>
>> > 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).<br>
>> ><br>
>> > 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()).<br>
>> ><br>
>> > 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.<br>
>> ><br>
>> > 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.<br>
>> ><br>
>> > Thanks,<br>
>> ><br>
>> > -Kurt Alfred Kluever (on behalf of Google's Java and Kotlin Ecosystem team)<br>
>> ><br>
>> > On Wed, Sep 3, 2025 at 1:53</span><span style="font-size:11.0pt;font-family:"Arial",sans-serif"> </span><span style="font-size:11.0pt">PM Pavel Rappo <pavel.rappo@gmail.com> wrote:<br>
>> >><br>
>> >> If I understood you correctly, you think we should also add<br>
>> >> Duration.MIN. If so, what use case do you envision for it? Or we add<br>
>> >> if purely for symmetry with Instant?<br>
>> >><br>
>> >> On Wed, Sep 3, 2025 at 6:43</span><span style="font-size:11.0pt;font-family:"Arial",sans-serif"> </span><span style="font-size:11.0pt">PM Pavel Rappo <pavel.rappo@gmail.com> wrote:<br>
>> >> ><br>
>> >> > On Wed, Sep 3, 2025 at 6:06</span><span style="font-size:11.0pt;font-family:"Arial",sans-serif"> </span><span style="font-size:11.0pt">PM Stephen Colebourne <scolebourne@joda.org> wrote:<br>
>> >> > ><br>
>> >> > > Hmm, yes. Not sure why that didn't get added in Java 8!<br>
>> >> > > The constants would be MAX/MIN as per classes like Instant.<br>
>> >> > > Stephen<br>
>> >> ><br>
>> >> > I thought that naming could be tricky :) The public constant<br>
>> >> > Duration.ZERO and the public method isZero() are already there.<br>
>> >> > However, it does not preclude us from naming a new constant MAX.<br>
>> ><br>
>> ><br>
>> ><br>
>> > --<br>
>> > kak<br>
>><br>
><br>
><br>
> --<br>
> kak<br>
><br>
><o:p></o:p></span></p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>