1

我正在使用 ZonedDateTime 来跟踪系统中发生的事件。例如

class PurchaseOrder {
    // The rest is skipped
    @Column(name = "created", columnDefinition = "TIMESTAMP WITH TIME ZONE", nullable = false)
    private ZonedDateTime created;
}

为了运行一些测试,我在内存数据库中使用了 hsqldb。我通过在配置 .properties 文件中指定它来运行 sql 脚本来填充它

spring.jpa.properties.hibernate.hbm2ddl.import_files=create-for-test.sql

在该文件中,我插入一条记录为

INSERT INTO purchase_order (id, consumer_id, provider_id, created, modified, purchase_order_status_id)
VALUES
(1, 1001, 1, '2017-01-11 11:45:20.523+01:00', NULL , 1);

它执行没有任何问题。

后来,当我从运行@NamedQuery 的数据库中获取这条记录时,我总是得到一个本地时区的值。发生读取的日志部分是:

Hibernate: select purchaseor0_.id as id1_52_, purchaseor0_.consumer_id as consumer5_52_, purchaseor0_.created as created2_52_,... from purchase_order purchaseor0_ where purchaseor0_.id=?
binding parameter [1] as [BIGINT] - [1]
extracted value ([id1_52_] : [BIGINT]) - [1]
extracted value ([consumer5_52_] : [BIGINT]) - [1001]
extracted value ([created2_52_] : [TIMESTAMP]) - [2017-01-11T11:45:20.523-08:00[America/Los_Angeles]]

所以:我用 TimeZone +01:00 插入它,Hibernate 堆栈在本地 TimeZone -08:00 中读回它。

有没有办法用正确的区域实际读取整个时间戳?

相同的代码在 Postgres 的生产环境中运行,并且时间戳在那里按预期运行(即我可以编写和读取 ZonedDateTime 并且区域信息不会丢失)。

编辑:@fredt Postgress 也返回 Timestamp,但“尊重”脚本中指定的时区。

例子:

UPDATE product
  SET
    published_from = '2017-01-01 00:00:00.000+01:00',
    published_to = '2017-01-31 00:00:00.000+01:00'
WHERE id = 3312;

和日志输出:

select distinct productimp0_.id as id1_39_, ...
  productimp0_.published_from as publish16_39_, productimp0_.published_to as publish17_39_, ...
from product productimp0_ where productimp0_.id=?


binding parameter [1] as [BIGINT] - [3312]
...
extracted value ([publish16_39_] : [TIMESTAMP]) - [2016-12-31T15:00-08:00[America/Los_Angeles]]
extracted value ([publish17_39_] : [TIMESTAMP]) - [2017-01-30T15:00-08:00[America/Los_Angeles]]

在 INSERT 语句中使用了 UTC+01(欧洲时间),休眠/驱动程序将其转换为本地时间(UTC-08)。只要我得到正确的时间点,这对我来说很好,因为在内部,完整的应用程序知道时区等。

4

0 回答 0