jdbc PostgreSQL 中的偏移时间(带时区的时间)
Posted
技术标签:
【中文标题】jdbc PostgreSQL 中的偏移时间(带时区的时间)【英文标题】:offset time (time with time zone) in jdbc PostgreSQL 【发布时间】:2018-10-15 07:55:39 【问题描述】:我正在尝试将java.time.OffsetTime
保存并检索到 PostgreSQL 版本 10.5,最新的 JDBC 驱动程序 (v 42.2.5)。
偏移时间已保存,但偏移量无效(它采用应用服务器偏移量而不是传递的偏移量)。
根据:https://jdbc.postgresql.org/documentation/head/8-date-time.html TIME WITH TIMEZONE
不支持(还没有?)。
注意 ZonedDateTime、Instant 和 OffsetTime / TIME [ WITHOUT 不支持 TIMEZONE ]
我的问题是,我想将偏移时间保存到 Postgres 中,那么还有哪些替代方法?
注意,我只关心时间(实际上是一个时间表),但我还需要知道偏移量,以便与 current_time 比较原因。
我的例子:
public class Customer
@Id
@GeneratedValue
private Long id;
private String name;
@Column(columnDefinition = "time with time zone")
private OffsetTime serviceTime;
@Column(columnDefinition = "timestamp with time zone")
private OffsetDateTime serviceDateTime;
private Instant createdDate = Instant.now();
主要:
OffsetTime serviceTime = OffsetTime.parse("10:00+02:00");
OffsetDateTime serviceDateTime = OffsetDateTime.now().with(serviceTime);
System.out.println(serviceTime);
System.out.println(serviceDateTime);
Customer customer = new Customer().withName("wael")
.withServiceTime(serviceTime)
.withServiceDateTime(serviceDateTime);
System.out.println("customer: " + customer);
customerRepository.save(customer);
Customer dbCustomer = customerRepository.findById(1L).get();
OffsetTime dbServiceTime = dbCustomer.getServiceTime();
OffsetDateTime dbServiceDateTime = dbCustomer.getServiceDateTime();
System.out.println(dbServiceTime);
System.out.println(dbServiceDateTime);
System.out.println("from db customer: " + dbCustomer);
数据库:
id created_date name service_date_time service_time
1 2018-10-15 10:38:27.814000 wael 2018-10-15 08:00:00.000000 10:00:00 +03:00
输出:
10:00+02:00
2018-10-15T10:00+02:00
customer: Customer(id=null, name=wael, serviceTime=10:00+02:00, serviceDateTime=2018-10-15T10:00+02:00, createdDate=2018-10-15T07:10:59.900Z)
10:00+03:00
2018-10-15T11:00+03:00
from db customer: Customer(id=1, name=wael, serviceTime=10:00+03:00, serviceDateTime=2018-10-15T11:00+03:00, createdDate=2018-10-15T07:10:59.900Z)
注意,我的机器时区是 +3(因此来自 db 的打印信息是 +3),我的数据库服务器是一个带有 UTC
日期时间设置的 docker 映像。
观察:
OffsetDatetime 已正确保存(作为 UTC)并正确检索。OffsetTime 保存不正确(应该是10:00:00 +02:00
或11:00:00 +03:00
甚至08:00:00 +00:00
而不是10:00:00 +03:00
,检索不正确!)
【问题讨论】:
您是否阅读了有关time with time zone
的comment in the manual? “带时区的类型 time 由 SQL 标准定义,但该定义显示的属性会导致**有问题的有用性” - 可能是一个简单的 time
列和一个 offset
列以分钟为单位存储偏移量是更好的选择。
请注意偏移量与时区不同。 +02:00
是与 UTC 的偏移量。 Europe/Paris
是一个时区(在我输入时恰好位于偏移量 +02:00
,但不是全年,也不总是在夏天)。如果您真正需要的是偏移量,那么将您的时间转换为 UTC 是否有效?如果您需要的是时区,我认为最好为时区 ID 定义一个 varchar
列。
@OleV.V.是的,正确,这是因为 DST 规则。我认为 Postgres 使用时区的概念来表达 Offset。
【参考方案1】:
使用 JPA 2.2,您还可以在 Postgresql 中使用 OffsetTime。
@Column(name = "offset_time", columnDefinition = "TIME WITH TIME ZONE")
private OffsetTime offsetTime;
这就是它在我的数据库中的存储方式:22:00:00.000000 +02:00
【讨论】:
以上是关于jdbc PostgreSQL 中的偏移时间(带时区的时间)的主要内容,如果未能解决你的问题,请参考以下文章
使用 JDBC 时,Oracle 的 REF CURSOR 在 Postgresql 中的等价物是啥?
如何通过 Spark 中的 jdbc 连接到 docker 托管的 postgresql 数据库?