Calling the JDKs Instant.toEpochMilli()
could result in an arithmetic overflow/underflow (e.g. Instant.MAX.toEpochMilli()
or Instant.MIN.toEpochMilli()
). I am looking for a simple way to avoid the arithmetic overflow and simply use Long.MAX_VALUE
. Here's my current code.
long seconds, millis;
seconds = deadline.getEpochSecond();
if (seconds > Long.MAX_VALUE / 1000 - 1)
millis = Long.MAX_VALUE;
else if (seconds < Long.MIN_VALUE / 1000 + 1)
millis = Long.MIN_VALUE;
else
millis = deadline.toEpochMilli();
It seems like there has to be a cleaner/clearer way to implement this. How would you implement this logic?
I have to be concerned about overflow/underflow because Instant.MAX
and Instant.MIN
are passed to the method where this code resides.
You can use java.lang.Math.addExact
. It will throw an ArithmeticException
if overflow occurs. It was added in Java 8.
EDIT
Ok, thinking about this question some more, I think I have a nice solution :
private Instant capped(Instant instant) {
Instant[] instants = {Instant.ofEpochMilli(Long.MIN_VALUE), instant, Instant.ofEpochMilli(Long.MAX_VALUE)};
Arrays.sort(instants);
return instants[1];
}
This method will return an Instant that will never overflow on toEpochMilli()
.
Simplifying your logic to :
millis = capped(deadline).toEpochMilli();
toEpochMilli
throws an exception in case of overflow, so you could just catch that exception:
try {
millis = deadline.toEpochMillis();
} catch (AritmeticException ignore) {
millis = deadline.getEpochSecond() < 0 ? Long.MIN_VALUE : Long.MAX_VALUE;
}
This code is simpler and safer than what is written in the question. It is safer because it doesn't try to re-implement the boundary logic inside toEpochMillis()
.
There might be a performance issue with throwing and catching exceptions. It depends on how often an exception is thrown. If an exception is thrown most of the time, then this will perform worse unless the JVM can optimize this away. If an exception is rarely thrown, then the performance will be fine.
The JVM might be able to optimize this away but maybe not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With