8273369: Computing micros between two instants unexpectedly overflows for some cases

Reviewed-by: lancea, rriggs, joehw
This commit is contained in:
Naoto Sato 2021-09-10 16:36:57 +00:00
parent efe3ed1e70
commit 81d2acee57
3 changed files with 52 additions and 6 deletions

View file

@ -61,6 +61,8 @@
*/
package java.time;
import static java.time.LocalTime.MICROS_PER_SECOND;
import static java.time.LocalTime.MILLIS_PER_SECOND;
import static java.time.LocalTime.NANOS_PER_SECOND;
import static java.time.LocalTime.SECONDS_PER_DAY;
import static java.time.LocalTime.SECONDS_PER_HOUR;
@ -1145,8 +1147,8 @@ public final class Instant
if (unit instanceof ChronoUnit chronoUnit) {
return switch (chronoUnit) {
case NANOS -> nanosUntil(end);
case MICROS -> nanosUntil(end) / 1000;
case MILLIS -> Math.subtractExact(end.toEpochMilli(), toEpochMilli());
case MICROS -> microsUntil(end);
case MILLIS -> millisUntil(end);
case SECONDS -> secondsUntil(end);
case MINUTES -> secondsUntil(end) / SECONDS_PER_MINUTE;
case HOURS -> secondsUntil(end) / SECONDS_PER_HOUR;
@ -1164,6 +1166,18 @@ public final class Instant
return Math.addExact(totalNanos, end.nanos - nanos);
}
private long microsUntil(Instant end) {
long secsDiff = Math.subtractExact(end.seconds, seconds);
long totalMicros = Math.multiplyExact(secsDiff, MICROS_PER_SECOND);
return Math.addExact(totalMicros, (end.nanos - nanos) / 1000);
}
private long millisUntil(Instant end) {
long secsDiff = Math.subtractExact(end.seconds, seconds);
long totalMillis = Math.multiplyExact(secsDiff, MILLIS_PER_SECOND);
return Math.addExact(totalMillis, (end.nanos - nanos) / 1000_000);
}
private long secondsUntil(Instant end) {
long secsDiff = Math.subtractExact(end.seconds, seconds);
long nanosDiff = end.nanos - nanos;