提问人:Paul Marcelin Bejan 提问时间:10/12/2023 最后编辑:Paul Marcelin Bejan 更新时间:10/14/2023 访问量:91
为什么 Instant 没有从 UTC 转换为 PostgreSQL 的时区?
Why Instant is not converted from UTC to timezone of PostgreSQL?
问:
在我的 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 小时的偏移量。
答:
即时
是时间轴上的瞬时点。它独立于时区,始终提供 UTC 中的时刻,即时区偏移量为“+00:00”,通常显示为 (代表祖鲁语)。Z
建议的做法是将值保留为jdbc.time_zone
UTC
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
这里有一个很好的教程,以下是PostgreSQL文档的内容:
对于具有时区的时间戳,内部存储的值始终为 UTC(世界协调时间,传统上称为格林威治平均值) 时间,格林威治标准时间)。
您始终可以将其转换为其他类型,例如,等以用于显示目的,例如Instant
ZonedDateTime
OffsetDateTime
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 一起使用。
评论
在已确定为没有时区的时间戳的文本中,PostgreSQL 将静默忽略任何时区指示。也就是说,结果值是从输入值中的日期/时间字段派生的,并且不会针对时区进行调整。
关于时间戳(TIMESTAMP WITHOUT TIME ZONE)和时间戳(TIMESTAMP WITH TIME ZONE)之间差异的一个很好的教程,可以在postgresqltutorial上找到示例
评论