Search code examples
javapostgresqlassertjspring-data-jdbc

3 digits difference between Java Instant and Postgres TIMESTAMPTZ


Given the following field in Java:

private Instant createdDate = Instant.now();

corresponding to the following field in Postgres:

created_date TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP;

and saved to database using Spring Data JDBC CrudRepository save(S entity).

When checking for equality the original object field and the saved one with:

assertThat(original_obj.getCreatedDate()).isEqualTo(database_obj.getCreatedDate());

I get the following mismatch:

org.opentest4j.AssertionFailedError:
      expected: 2023-05-29T10:41:12.555839137Z
       but was: 2023-05-29T10:41:12.555839Z

It appears the Instant loaded from database has 3 less digits than the original Instant.

How can I make the two instants match? Why are they different?


Solution

  • Java Time stores time with up to 1 nanosecond precision, while Postgres stores microseconds.

    You can either allow delta in the comparison as suggested in the comments or.. an easier solution would be to just truncate the date in Java if you don't care about those nanos:

    Instant createdDate = Instant.now().truncatedTo(ChronoUnit.MICROS)