8068958: Timestamp.from(Instant) should throw when conversion is not possible

Reviewed-by: rgiulietti, rriggs
This commit is contained in:
Eamonn McManus 2023-12-23 22:53:23 +00:00
parent 28c82bf18d
commit 4fc6b0ffa4
2 changed files with 28 additions and 3 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2023, 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
@ -542,7 +542,7 @@ public class Timestamp extends java.util.Date {
*/
public static Timestamp from(Instant instant) {
try {
Timestamp stamp = new Timestamp(instant.getEpochSecond() * MILLIS_PER_SECOND);
Timestamp stamp = new Timestamp(Math.multiplyExact(instant.getEpochSecond(), MILLIS_PER_SECOND));
stamp.nanos = instant.getNano();
return stamp;
} catch (ArithmeticException ex) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2023, 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
@ -642,6 +642,31 @@ public class TimestampTests extends BaseTest {
assertEquals(ts1.toString(), ts, "ts1.toString() != ts");
}
@Test
public void test53() {
// The latest Instant that can be converted to a Timestamp.
Instant instant1 = Instant.ofEpochSecond(Long.MAX_VALUE / 1000, 999_999_999);
assertEquals(Timestamp.from(instant1).toInstant(), instant1);
// One nanosecond more, and converting it gets an overflow.
Instant instant2 = instant1.plusNanos(1);
expectThrows(IllegalArgumentException.class, () -> Timestamp.from(instant2));
// The earliest Instant that can be converted to a Timestamp.
Instant instant3 = Instant.ofEpochSecond(Long.MIN_VALUE / 1000, 0);
assertEquals(Timestamp.from(instant3).toInstant(), instant3);
// One nanosecond less, and converting it gets an overflow.
Instant instant4 = instant3.minusNanos(1);
expectThrows(IllegalArgumentException.class, () -> Timestamp.from(instant4));
// The latest possible Instant will certainly overflow.
expectThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MAX));
// The earliest possible Instant will certainly overflow.
expectThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MIN));
}
/*
* DataProvider used to provide Timestamps which are not valid and are used
* to validate that an IllegalArgumentException will be thrown from the