JPQL 查询参数中的时间戳未转换为 UTC

Posted

技术标签:

【中文标题】JPQL 查询参数中的时间戳未转换为 UTC【英文标题】:Timestamp in JPQL query parameter not converted to UTC 【发布时间】:2020-11-20 08:35:55 【问题描述】:

我知道 *** 上已经有大量与时区相关的问题,但遗憾的是我没有找到一个描述我的问题的问题。

所讨论的实体是一个事件,其起点和终点为java.util.Date。在数据库中,这些以 UTC 格式保存为时间戳

我目前正在尝试开发一种方法,使所有事件都在某个时间段内重叠。查询本身有效,但参数以我的本地时区而不是 UTC 发送到数据库。

public List<EventEntity> getEventsInPeriod(Date start, Date end) 
    return em.createQuery("Select e from EventEntity e where e.startTime < :periodEnd and e.endTime > :periodStart", EventEntity.class)
        .setParameter("periodStart", start)
        .setParameter("periodEnd", end)
        .getResultList();

如果在执行查询之前调用TimeZone.setDefault(TimeZone.getTimeZone("UTC")),则返回正确的结果。

我认为Date 就像一个时间戳(相对于 unix start),因此对时区不敏感。当我查看日志中的查询时,我可以看到日期在当前时区中作为字符串传递。例如:2020-08-01 15:30:00.0

【问题讨论】:

我不明白这个问题。您如何创建开始/结束日期对象。如果您使用“2020-08-01 15:30:00.0”创建,则此字符串将在本地时区格式化,并且不会与“2020-08-01 15:30:00.0 UTC”相同。它还可能与数据库、用于列的类型以及它的默认时区处理有关。 【参考方案1】:

我发现的解决方法是在将日期传递给查询之前将当前时区偏移量添加到日期。

Date startInUtc = new Date(start.getTime() + offset);
...
query.setParameter("periodStart", startInUtc)

这不是很好,因为对于持久化日期,它们会自动转换,而对于查询,我必须手动执行此操作。所以我仍然愿意寻求更好的解决方案。

【讨论】:

以上是关于JPQL 查询参数中的时间戳未转换为 UTC的主要内容,如果未能解决你的问题,请参考以下文章

bigquery - zeppelin 时间戳未呈现为日期

将UTC时间戳转换为熊猫中的本地时区问题

将UTC时间戳转换为C中的纪元时间[重复]

时间戳未打印在 FFMPEG 的缩略图上

BigQuery 自动将时间戳时区转换为 UTC

当时间戳未被归类为索引时,如何按时间戳对数据帧进行切片?