繁体   English   中英

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

[英]UTC Unix timestamp storage in HSQLDB from Java program in wrong timezone

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

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

我的尝试 - 文件指出:

使用PreparedStatement或CallableStatement接口将datetime值发送到数据库时,Java对象将转换为ready或callable语句参数的类型。 此类型可以是DATE,TIME或TIMESTAMP(带或不带时区)。 时区位移是JDBC会话的时区。

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

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

其他尝试

我还尝试使用TIMESTAMP WITH TIME ZONE列,而不设置会话TZ。 在这种情况下,数据库存储'本地时间+2',我可以从中提取正确的时间戳。 这是边缘荒谬 - 这意味着HSQLDB驱动程序采用Java时间戳(UTC),将其正确解释为UTC,将其转换为JVM默认TZ,然后将其发送到DB。 我不想要数据库中的TZ信息 - 不需要它。 (注意:改变会话TZ没有影响 - 发出的SQL命令总是与我的本地TZ ...让你想知道SET TZ命令的重点是什么)

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

另外值得注意的是: 这个问题似乎有关,但提供的答案基本上是破解我想避免的每个SQL命令......

我的问题

如何将我的UTC Java时间戳存储在HSQLDB中? SET TIME ZONE订单的目的是什么?

谢谢阅读。

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM