JDK-8074032 : Instant.ofEpochMilli(millis).toEpochMilli() can throw arithmetic overflow in toEpochMilli()
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.time
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-02-27
  • Updated: 2016-01-14
  • Resolved: 2015-03-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u72Fixed 9 b54Fixed
Related Reports
Duplicate :  
Description
The following test:

        for (Object[] test : new Object[][] {
            {"Long.MAX_VALUE",Long.MAX_VALUE},
            {"Long.MAX_VALUE-1",Long.MAX_VALUE-1},
            {"1",1L},
            {"0", 0L},
            {"-1",-1L},
            {"Long.MIN_VALUE+1",Long.MIN_VALUE+1},
            {"Long.MIN_VALUE",Long.MIN_VALUE}
            }) {

            long millis = (Long)test[1];
            System.err.println("Testing with " + test[0] +": "+millis+"L");
            Instant i1 = Instant.ofEpochMilli(millis);
            System.err.println("Instant.ofEpochMilli(): " + i1);
            long seconds = i1.getEpochSecond();
            System.err.println("Instant.getEpochSecond(): " + seconds);
            System.err.println("millis/1000: " + millis/1000);

            long millis2 = i1.toEpochMilli();
            System.err.println("Instant.toEpochMilli(): " + millis2+"L");
            if (millis2 != millis) {
                throw new RuntimeException("Test failed for " + test[0]
                        + "\n\texpected: "+millis+"L"
                        + "\n\tactual:   "+millis2+"L");
            }
        }

causes an arithmetic overflow for Long.MIN_VALUE+1 and Long.MIN_VALUE. 

Exception in thread "main" java.lang.ArithmeticException: long overflow
at java.lang.Math.multiplyExact(Math.java:915)
at java.time.Instant.toEpochMilli(Instant.java:1232)

Comments
The following patch solves the issue: --- a/src/java.base/share/classes/java/time/Instant.java +++ b/src/java.base/share/classes/java/time/Instant.java @@ -1229,9 +1229,15 @@ * @throws ArithmeticException if numeric overflow occurs */ public long toEpochMilli() { + if (seconds < 0 && nanos > 0) { + long millis = Math.multiplyExact(seconds+1, 1000); + long adjustment = nanos / 1000_000 - 1000; + return millis + adjustment; + } else { long millis = Math.multiplyExact(seconds, 1000); return millis + nanos / 1000_000; } + } //----------------------------------------------------------------------- /**
27-02-2015