从PostgreSQL获取ZonedDateTime时区被转为UTC的问题求助
我有一个名为Turno的实体,包含ZonedDateTime类型的fechaTurno属性,代码如下:
@Column(name = "fecha", nullable = false) @Temporal(TemporalType.TIMESTAMP) private ZonedDateTime fechaTurno;
保存实体时,日期和时区能正确存入PostgreSQL,但从后端查询数据时,时区会被转换为UTC。
PostgreSQL中存储的正确日期:
查询后Java中得到的UTC时区值:
我已做了以下配置:
application.properties
spring.jackson.time-zone=America/Argentina/Buenos_Aires spring.jpa.properties.hibernate.jdbc.time_zone=America/Argentina/Buenos_Aires
主类代码
@PostConstruct public void init(){ TimeZone.setDefault(TimeZone.getTimeZone("America/Argentina/Buenos_Aires")); }
需要实现查询时自动获取带正确时区(GMT-03)的日期,无需每次查询后手动修改。
1. 修正实体字段的注解配置
@Temporal(TemporalType.TIMESTAMP)是为旧版java.util.Date/Calendar设计的注解,和ZonedDateTime不兼容,直接移除该注解,并明确数据库字段类型为带时区的时间戳:
@Column(name = "fecha", nullable = false, columnDefinition = "TIMESTAMP WITH TIME ZONE") private ZonedDateTime fechaTurno;
同时确保PostgreSQL中对应的字段类型是timestamptz(即TIMESTAMP WITH TIME ZONE),让Hibernate能正确映射时区信息。
2. 补充Hibernate的Java8日期类型时区配置
在application.properties中添加针对Java8+日期类型的专属时区配置:
spring.jpa.properties.hibernate.type.preferred_time_zone=America/Argentina/Buenos_Aires
这个配置专门用于ZonedDateTime、OffsetDateTime等新日期类型的时区映射,和hibernate.jdbc.time_zone配合,避免查询时自动转成UTC。
3. 强化Jackson序列化时区配置
如果是接口返回前端时时区异常,除了spring.jackson.time-zone,可以手动配置Jackson的ObjectMapper确保序列化行为:
@Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.setTimeZone(TimeZone.getTimeZone("America/Argentina/Buenos_Aires")); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return mapper; }
4. 明确JDBC连接的时区参数
在数据库连接URL中指定时区,确保JDBC驱动和数据库交互时使用目标时区:
spring.datasource.url=jdbc:postgresql://localhost:5432/your_db?serverTimezone=America/Argentina/Buenos_Aires&useTimezone=true
内容的提问来源于stack exchange,提问作者Martin Isasmendi

