Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8272999

Duration.toMillis() may accidentally wrap negative nanos

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 9
    • core-libs

      We observe a different behavior between jdk8u and jdk9+. eg.:

      % cat Test.java
      import java.time.Duration;

      public class Test {

           public static void main(String []args){
              System.out.println(Duration.ofNanos(-57282645800L).toMillis());
           }
      }

      % JavaSE8/jdk1.8/bin/java -Xmx128M -Xms16M Test
      -57283
      % JavaSE11/jdk-11/bin/java -Xmx128M -Xms16M Test
      -57282

      The answer depends on the intermediate representation of a Duration. for Duration.ofNanos(-57282645800L), its seconds = -58 and nanos = 717354200. JDK-8146747 introduces a change for java.time.Duration.toMillis(). The new toMillis() breaks this comment of nanos because tempNanos could be negative.

          /**
           * The number of nanoseconds in the duration, expressed as a fraction of the
           * number of seconds. This is always positive, and never exceeds 999,999,999.
           */
          private final int nanos;

      I am not saying this is a bug, but the results are different from jdk8u and later JDKs.

      If we only want to deal with Long.MIN_VALUE, why do we borrow a second for all negative durations?
       
             if (tempSeconds < 0) {
                  // change the seconds and nano value to
                  // handle Long.MIN_VALUE case
                  tempSeconds = tempSeconds + 1;
                  tempNanos = tempNanos - NANOS_PER_SECOND;
              }

          

            naoto Naoto Sato
            xliu Xin Liu
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: