为什么 Instant 没有从 UTC 转换为 PostgreSQL 的时区?

Why Instant is not converted from UTC to timezone of PostgreSQL?

提问人:Paul Marcelin Bejan 提问时间:10/12/2023 最后编辑:Paul Marcelin Bejan 更新时间:10/14/2023 访问量:91

问:

在我的 PostgreSQL 上,如果我运行脚本:

show timezone;

它返回

Europe/Rome

所以据此,我配置了

spring.jpa.properties.hibernate.jdbc.time_zone: Europe/Rome

我有一个表 TestPostgre,其中包含时间戳数据类型的列datetime_using_instant

@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;
    
}

使用 JpaRepository:

@Repository
public interface TestPostgreRepository extends JpaRepository<TestPostgre, String> {
    
}

保存 dateTimeUsingInstant 值为 2023-10-11T12:30:00Z 的 TestPostgre 实例时,在 PostgreSQL 上,该值仍为 2023-10-11 12:30:00.000,但在 UTC 和欧洲/罗马之间有 2 小时的偏移量。

Java PostgreSQL 休眠 java-time

评论


答:

0赞 Arvind Kumar Avinash 10/12/2023 #1

即时是时间轴上的瞬时点。它独立于时区,始终提供 UTC 中的时刻,即时区偏移量为“+00:00”,通常显示为 (代表祖鲁语)。Z

建议的做法是将值保留为jdbc.time_zoneUTC

spring.jpa.properties.hibernate.jdbc.time_zone=UTC

这里有一个很好的教程,以下是PostgreSQL文档的内容:

对于具有时区的时间戳,内部存储的值始终为 UTC(世界协调时间,传统上称为格林威治平均值) 时间,格林威治标准时间)。

您始终可以将其转换为其他类型,例如,等以用于显示目的,例如InstantZonedDateTimeOffsetDateTime

Instant instant = Instant.now();
ZonedDateTime zdt = instant.atZone(ZoneId.of("Europe/Rome"));
System.out.println(instant);
System.out.println(zdt);

示例运行的输出:

2023-10-12T11:18:44.036798Z
2023-10-12T13:18:44.036798+02:00[Europe/Rome]

在线演示

Trail: Date Time 了解有关新式日期时间 API 的更多信息。


查看此答案和此答案,了解如何将 java.time API 与 JDBC 一起使用。

评论

0赞 Paul Marcelin Bejan 10/12/2023
jdbc.time_zone属性必须与数据库时区匹配?
0赞 Andrey B. Panfilov 10/12/2023
@PaulMarcelinBejan肯定不是,该功能是在 HHH-10399 中引入的,它明确指出应该是 DB 时区。
1赞 Paul Marcelin Bejan 10/14/2023 #2

PostgreSQL 时间戳

在已确定为没有时区的时间戳的文本中,PostgreSQL 将静默忽略任何时区指示。也就是说,结果值是从输入中的日期/时间字段派生的,并且不会针对时区进行调整

关于时间戳(TIMESTAMP WITHOUT TIME ZONE)和时间戳(TIMESTAMP WITH TIME ZONE)之间差异的一个很好的教程,可以在postgresqltutorial上找到示例