我用两个Instant字段编写了一个简单的Java实体:
@Entity
@Table(name = "tb_foo")
public class Foo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
private Instant date1;
@Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
private Instant date2;
...
然后,我在项目的资源根文件夹中编写了一个简单的import.sql,以测试UTC / Local是否正常工作:INSERT INTO tb_foo (date1, date2) VALUES ('2020-07-22T20:50:01.12345Z', NOW());
由于我的本地时区是GMT-3,因此上述20:50:01应该在客户端上显示为17:50:01,并且NOW()应该与我的本地时间等效(在我测试的那一刻大约是0:25) )。我在H2数据库中对其进行了测试,并且效果很好:这是JPA自动为H2生成的DDL和INSERT:
create table tb_foo (
id bigint generated by default as identity,
date1 TIMESTAMP WITHOUT TIME ZONE,
date2 TIMESTAMP WITHOUT TIME ZONE,
primary key (id)
)
INSERT INTO tb_foo (date1, date2) VALUES ('2020-07-22T20:50:01.12345Z', NOW())
但是,当我在Postgres(12.x)上测试相同的Java和SQL代码时,它不起作用(20h UTC显示为20而不是17):这是JPA自动生成到Postgresql的DDL和INSERT:
create table tb_foo (
id int8 generated by default as identity,
date1 TIMESTAMP WITHOUT TIME ZONE,
date2 TIMESTAMP WITHOUT TIME ZONE,
primary key (id)
)
INSERT INTO tb_foo (date1, date2) VALUES ('2020-07-22T20:50:01.12345Z', NOW())
我错过了什么?更新:
我进行了另一个测试:我通过Java(不是SQL INSERT)编写了另一个数据库插入操作:
Foo foo = new Foo(null, Instant.parse("2020-07-23T20:50:01Z"), Instant.now());
fooRepository.save(foo);
这次将字面的UTC时间戳20:50正确地插入了Postgresql中!它在pgadmin客户端上显示为17:50!所以也许正确的问题是:如何在SQL INSERT调用中正确指定Postgresql的文字UTC时间戳以将其存储在没有时区的时间戳中?
我用两种方法尝试过:
INSERT INTO tb_foo (date1, date2) VALUES ('2020-07-22T20:50:01.12345Z', NOW());
INSERT INTO tb_foo (date1, date2) VALUES ('2020-07-22 20:50:01 +00', NOW());
而且两者都不起作用(它们在GMT-03系统中的pgadmin客户端上都显示20:50而不是17:50)。
最佳答案
可能由于以下原因:如果在输入中为 time指定了时区,而没有时区,则将其忽略。它会忽略您的“Z”,并插入显示的日期时间。
https://www.postgresql.org/docs/12/datatype-datetime.html
关于java - JPA,Postgresql和SQL INSERT语句:UTC时间戳无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63046586/