On my PostgreSQL, if I run the script:
show timezone;
it returns
Europe/Rome
so according to this, I have configured
spring.jpa.properties.hibernate.jdbc.time_zone: Europe/Rome
I have a table TestPostgre with a column datetime_using_instant of timestamp data type.
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@Entity
@Table(name = "test_postgre")
public class TestPostgre {
@Id
@Column(name = "pk", nullable = false)
private String pk;
@Column(name = "datetime_using_instant", nullable = false)
private Instant dateTimeUsingInstant;
}
Using JpaRepository:
@Repository
public interface TestPostgreRepository extends JpaRepository<TestPostgre, String> {
}
when saving a TestPostgre instance with dateTimeUsingInstant value of 2023-10-11T12:30:00Z, on PostgreSQL the value is still 2023-10-11 12:30:00.000, but between UTC and Europe/Rome there are 2 hours of offset.
2
Answers
PostgreSQL Time Stamps
In a literal that has been determined to be timestamp without time zone, PostgreSQL will silently ignore any time zone indication. That is, the resulting value is derived from the date/time fields in the input value, and is not adjusted for time zone.
A nice tutorial for the difference between timestamp (TIMESTAMP WITHOUT TIME ZONE) and timestampz (TIMESTAMP WITH TIME ZONE) with examples can be found at postgresqltutorial
Instant
is an instantaneous point on the timeline. It is independent of a time zone and always provides a moment in UTC i.e. with a time zone offset of "+00:00", typically displayed asZ
(stands for Zulu).The recommended practice is to keep the value of
jdbc.time_zone
asUTC
There is a good tutorial here and here is what the PostgreSQL documentation says:
You can always convert an
Instant
into other types e.g.ZonedDateTime
,OffsetDateTime
etc. for display purposes e.g.Output from a sample run:
Online Demo
Learn more about the modern Date-Time API from Trail: Date Time.
Check this answer and this answer to learn how to use
java.time
API with JDBC.