Reputation: 92580
I have a JPA entity class with an OffsetDateTime
field like this:
@Entity
class MyEntity(clock: Clock) {
// ...
val created: OffsetDateTime = OffsetDateTime.now(clock)
}
In a repository test I check that the date is corretly mapped:
assertThat(entity.created).isEqualTo(defaultDateTime)
If I compare the underlying Instant
(and not also the offset) with OffsetDateTime#isEqual
it works:
assertThat(entity.created.isEqual(defaultDateTime)).isTrue()
defaultDateTime
and the clock
are created with this code:
val defaultDateTime: OffsetDateTime =
OffsetDateTime.of(2019, 6, 15, 11, 48, 59, 0, ZoneOffset.UTC)
fun createTestClock(dateTime: OffsetDateTime = defaultDateTime) =
Clock.fixed(dateTime.toInstant(), ZoneId.of("UTC"))
But if I run my test, the time differs by exactly 2 hours (what is the actual offset in my region, central europe). The PostgreSQL database returns GMT
if I query the timezone with show timezone;
.
The column data type is:
timestamp with time zone not null
Setting the respective Hibernate property doesn't help:
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
What is wrong?
Upvotes: 4
Views: 3177
Reputation: 432
I believe that UTC and GMT have a (UTC) time offset of 0. Central Europe uses CET (Central European Time), which currently has an (UTC) offset of +2. This would explain the answer being off by 2hrs.
I would recommend maybe setting the default timezone in java (in your main application)
@PostConstruct
void started() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
and/or change the DB Timezone like
spring.jpa.properties.hibernate.jdbc.time_zone=UTC;
to
spring.jpa.properties.hibernate.jdbc.time_zone=CET;
I think the issue may be java using your default timezone on your machine. When it compares the Entity I believe it compares them as UTC strings, so they would match, but if you compare the offset, your local may be CET (+2) while the timestamp is UTC/GMT (+0)
This is one possibility, just my knowledge of Java and Postrges more than Spring.
Upvotes: 3