8074032: Instant.ofEpochMilli(millis).toEpochMilli() can throw arithmetic overflow in toEpochMilli()
authordfuchs
Mon, 02 Mar 2015 14:46:10 +0100
changeset 29230 19c7760bc203
parent 29229 522667854295
child 29231 e515c8f5bbec
child 29239 d3780f05b8f1
8074032: Instant.ofEpochMilli(millis).toEpochMilli() can throw arithmetic overflow in toEpochMilli() Summary: Instant.toEpochMilli() now takes into account the sign of the 'seconds' field. Reviewed-by: rriggs, scolebourne
jdk/src/java.base/share/classes/java/time/Instant.java
jdk/test/java/time/test/java/time/TestInstant.java
--- a/jdk/src/java.base/share/classes/java/time/Instant.java	Mon Mar 02 14:18:05 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/time/Instant.java	Mon Mar 02 14:46:10 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1229,8 +1229,14 @@
      * @throws ArithmeticException if numeric overflow occurs
      */
     public long toEpochMilli() {
-        long millis = Math.multiplyExact(seconds, 1000);
-        return millis + nanos / 1000_000;
+        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;
+        }
     }
 
     //-----------------------------------------------------------------------
--- a/jdk/test/java/time/test/java/time/TestInstant.java	Mon Mar 02 14:18:05 2015 +0100
+++ b/jdk/test/java/time/test/java/time/TestInstant.java	Mon Mar 02 14:46:10 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,6 +62,8 @@
 import java.time.Instant;
 
 import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.assertEquals;
 
 /**
  * Test Instant.
@@ -74,4 +76,24 @@
         assertImmutable(Instant.class);
     }
 
+    @DataProvider(name="sampleEpochMillis")
+    private Object[][] provider_sampleEpochMillis() {
+        return 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}
+        };
+    }
+
+    @Test(dataProvider="sampleEpochMillis")
+    public void test_epochMillis(String name, long millis) {
+        Instant t1 = Instant.ofEpochMilli(millis);
+        long m = t1.toEpochMilli();
+        assertEquals(millis, m, name);
+    }
+
 }