Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Has conversion between Instant and Date changed from Java 8 to 11?

When updating from Java 8 to 11 I noticed the following difference, which can break logical flow quite seriously:

Given the following code

final Instant now = Instant.now();
System.out.println(now.minusNanos(1).isBefore(now));
System.out.println(Date.from(now.minusNanos(1)).before(Date.from(now)));

Executed on Java 8 (corretto 1.8.0_232) prints:

true
true

Contrary Java 11 (corretto 11.0.0.5_10) prints:

true
false

So my Question is: Why exactly does this happen and is it documented somewhere?

like image 660
8hZWKA Avatar asked Dec 30 '22 13:12

8hZWKA


1 Answers

What changed is the output of Instant.now(). From the documentation of Clock:

This clock is based on the best available system clock. This may use System.currentTimeMillis(), or a higher resolution clock if one is available.

OpenJDK 11 uses a higher resolution clock, and so returns an Instant with a nanosecond part. Date only has millisecond precision, so it implicitly truncates the Instant when converting between the two.

You can get equivalent behaviour in JDK 8 and 11 by calling Instant.now().truncatedTo(ChronoUnit.MILLIS), or by using Clock#tickMillis

like image 83
MikeFHay Avatar answered Jan 29 '23 23:01

MikeFHay