PostgreSQL 9.2 JDBC驱动程序使用客户端时区?

时间:2013-08-26 15:47:01

标签: postgresql jdbc timezone

我使用PostgreSQL数据库和PostgreSQL JDBC驱动程序遇到了一个有趣的挑战。似乎最新版本的驱动程序9.2在执行日期/时间匹配时使用客户端时区。

当服务器(JasperReports Server)设置为UTC且数据库服务器设置为US / Eastern时,这会成为问题。

如果我从设置为UTC时区的客户端运行以下查询,则使用9.0 JDBC驱动程序和9.2 JDBC驱动程序得到不同的结果。

select now(), extract(timezone FROM now()), current_setting('TIMEZONE'), now()-interval '1 hour' as "1HourAgo"

使用9.0 JDBC驱动程序的结果:

now                         date_part   current_setting     1HourAgo
2013-08-26 15:33:57.590089  -14,400     US/Eastern          2013-08-26 14:33:57.590089

使用9.2 JDBC驱动程序的结果:

now                         date_part   current_setting     1HourAgo
2013-08-26 15:41:49.067903  0           UTC                 2013-08-26 14:41:49.067903

这导致查询中的WHERE语句返回不正确的结果。例如,

WHERE end_time between now() - interval '1 hour' and now()

使用9,0驱动程序按预期工作,但使用9,2驱动程序返回无结果,因为驱动程序似乎偏移了end_time的值以匹配UTC(客户端的时区)。以下是一种解决方法,但是一个丑陋的方法:

WHERE end_time at time zone 'EDT' between now() - interval '1 hour' and now()

问题:

  1. 之前还有其他人遇到过这个吗?
  2. 这种行为改变是否有解释?我无法在JDBC发行说明中找到任何内容
  3. 除了将驱动程序回滚到旧版本之外,有关如何解决此问题的任何建议吗?
  4. 谢谢!

5 个答案:

答案 0 :(得分:7)

我自己也遇到了这个问题。我验证了postgres jdbc驱动程序确实从jvm中获取了连接时区,我无法找到覆盖此行为的方法。如果他们为此提供了一个jdbc url连接参数,那真的很不错。

作为一种解决方法,我发现我的连接池库(HikariCP)可以为每个新连接执行sql语句:

hikariConfig.setConnectionInitSql("set time zone 'UTC'");

答案 1 :(得分:5)

JDBC标准(和API文档)需要使用本地时区作为默认时区,并由PreparedStatement.setTimestamp明确指出。但是,它也适用于JDBC设置或检索时间相关数据的所有其他区域。

另请参阅我对Is java.sql.Timestamp timezone specific?

的回答

答案 2 :(得分:1)

以防其他人为此而烦恼 - 您可以编辑启动SQLDeveloper的“conf”文件并添加以下行:

AddVMOption -Duser.timezone=UTC

我在我的机器上找到了这个文件:

/opt/sqldeveloper/ide/bin/ide.conf

感谢@a_horse_with_no_name指出我正确的方向并在其中一个答案中发表评论

答案 3 :(得分:1)

短版尝试:

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

您好,我们遇到了客户端和服务器时区未匹配的问题,我们需要使用“ UTC”运行单元测试。通过查看postgres jdbc驱动程序的源代码(这是测试代码),我们通过在获取连接之前更改jvm内部的TZ来“修复”它。

答案 4 :(得分:0)

我不知道JasperReports,但一般来说,使用JSR-310(Java 8)日期/时间类型(由JDBC 4.2支持)应该可以工作,而不必担心数据库服务器和客户端之间的时区不匹配。 / p>

请参阅PostgreSQL JDBC驱动程序文档中的Using Java 8 Date and Time classes