JTS*_*man 19 postgresql timezone jdbc
我使用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"
Run Code Online (Sandbox Code Playgroud)
使用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
Run Code Online (Sandbox Code Playgroud)
结果使用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
Run Code Online (Sandbox Code Playgroud)
这导致查询中的WHERE语句返回不正确的结果.例如,
WHERE end_time between now() - interval '1 hour' and now()
Run Code Online (Sandbox Code Playgroud)
使用9,0驱动程序按预期工作,但使用9,2驱动程序返回无结果,因为驱动程序似乎偏移了end_time的值以匹配UTC(客户端的时区).以下是一种解决方法,但是一个丑陋的方法:
WHERE end_time at time zone 'EDT' between now() - interval '1 hour' and now()
Run Code Online (Sandbox Code Playgroud)
问题:
谢谢!
我自己也遇到过这个问题.我验证了postgres jdbc驱动程序确实从jvm中获取了连接时区,我无法找到覆盖此行为的方法.如果他们为此提供了一个jdbc url连接参数,那真的很好.
作为一种解决方法,我发现我的连接池库(HikariCP)可以为每个新连接执行sql语句:
hikariConfig.setConnectionInitSql("set time zone 'UTC'");
Run Code Online (Sandbox Code Playgroud)
JDBC标准(和API文档)需要使用本地时区作为默认时区,并由PreparedStatement.setTimestamp明确指定.但是,它也适用于JDBC设置或检索时间相关数据的所有其他区域.
另请参阅我对java.sql.Timestamp时区特定的答案?