java - UTC Unix 时间戳存储在错误时区的 Java 程序中的 HSQLDB 中

标签 java date timezone hsqldb utc

我正在尝试了解如何存储 Unix timestamp (即自 1970 年以来的秒数,以 UTC/GMT 时区表示)在 HSQLDB 内嵌入式文件数据库。但是,我还没有理解 TZ 处理如何与 HSQL 一起工作。

我的程序将在不同区域使用,因此必须使用 UTC。此外,我无法更改默认时区(与 java.util.TimeZone.setDefault 一样),因为它将嵌入到其他程序中,因此不应更改环境。

我的尝试 - 文档指出:

When datetime values are sent to the database using the PreparedStatement or CallableStatement interfaces, the Java object is converted to the type of the prepared or callable statement parameter. This type may be DATE, TIME, or TIMESTAMP (with or without time zone). The time zone displacement is the time zone of the JDBC session.

所以我在数据库中使用了一个 TIMESTAMP 列(没有时区 - 默认值),并发出 SET TIME ZONE INTERVAL '0:00' HOUR TO MINUTE(将 session 置于 UTC TZ ) 然后 INSERT INTO TEST VALUES(?) 用 ?是包含正确 Unix 值的 Java 时间戳对象(与 GMT 相关,测试正常)。

遗憾的是,在这种情况下,数据库的 SQL 日志显示时间戳已恢复为我的本地时区 (+2)。对于时间戳 1442132237635(UTC 为 8H17,+2 为 10H17),我们在日志中得到 TIMESTAMP'2015-09-13 10:17:17.602000'。错误的结果……似乎改变 session 时区完全没有任何影响(我试过+14、-14……没有改变)。然而,SET 命令被正确执行 - 它出现在 SQL 日志中,并且 TIMEZONE() 的值随后发生变化。

其他尝试

我还尝试使用 TIMESTAMP WITH TIME ZONE 列,但没有设置 session TZ。在那种情况下,数据库存储“本地时间+2”,我可以从中提取正确的时间戳。这是非常荒谬的——这意味着 HSQLDB 驱动程序采用 Java 时间戳 (UTC),将其正确解释为 UTC,将其转换为 JVM 默认 TZ,然后将其发送到数据库。我不想要数据库中的 TZ 信息——不需要它。 (注意:更改 session TZ 没有影响 - 发出的 SQL 命令始终与我的本地 TZ 一起...让您想知道 SET TZ 命令的意义何在)

将默认的 JVM TZ 更改为 UTC 是可行的,但如上所述我不能这样做。

另请注意:this question似乎相关但提供的答案基本上是破解我想避免的每个 SQL 命令...

我的问题

我怎样才能简单地将我的 UTC Java 时间戳存储在 HSQLDB 中? SET TIME ZONE 命令的目的是什么?

感谢阅读。

最佳答案

您的第一次尝试是正确的,并将返回正确的结果。

您的数据库位于 UTC+2 时区。您正在连接,就好像您是 UTC 时区的远程用户一样。

时间戳的日志存储没有你说的错误。日志存储不是供数据库的用户读取的。数据库将其日志存储在您所在位置的时区中。下次它读取日志时,它会根据您的数据库时区读取并解释它(与 session 时区无关)。因此,在日志中存储为 10:17 的时间在 UTC 中将是 8:17。

使用 TIMESTAMP WITHOUT TIME ZONE,数据库文件无法移动到不同的时区,因为时间戳将根据新位置的时区进行解释。

SET TIME ZONE 语句的作用是允许在存储数据时进行正确的调整。它不会更改以前存储的数据。当然,如果时间存储为 8:17,则无论何时何地访问该时间都应将其读取为 8:17。

为了获得最佳的可移植性,请使用 TIMESTAMP WITH TIME ZONE。即使您移动数据库文件,它存储和检索数据的方式也是正确的。

关于java - UTC Unix 时间戳存储在错误时区的 Java 程序中的 HSQLDB 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32547994/

相关文章:

javascript - 如何在各种浏览器中以用户本地时间显示我的 javascript 日期对象?

php - 一个月差距计算

javascript - 无法将 UTC 转换为 PST,反之亦然

ios - 登机牌(pk.pass 文件)- 如何修复切换时区后 iPhone 提醒时间错误的问题

java - 如何从属性中删除键并保持原始顺序?

Java 有效日期闰年

java - 如何向 VSCode Java 调试器提供启动选项参数

java - 微软Azure表存储: CloudTable() error no suggestions available

Excel 日期公式查找下个月第二个工作日的日期

ruby-on-rails - rails//白天按时区查询