PostgreSQL(PolarDB PG 16)在通过JDBC执行SELECT now() 时,总是返回Asia/Shanghai时区,即使数据库时区设置为UTC
我正在使用 PolarDB for PostgreSQL 16,以及一个使用PostgreSQL JDBC驱动的Java应用。
在我的Java代码中,我执行一个简单查询:
String query = "SELECT now();";
try {
conn2 = driver2.connect(url2, info2);
stmt2 = conn2.prepareStatement(query);
rs2 = stmt2.executeQuery();
while (rs2.next()) {
String result = rs2.getString(1);
System.out.println("Query Result: " + result);
}
} catch (SQLException e) {
System.out.println("Connection failed!");
e.printStackTrace();
} finally {
try {
if (rs1 != null) rs1.close();
if (rs2 != null) rs2.close();
if (stmt1 != null) stmt1.close();
if (stmt2 != null) stmt2.close();
if (conn1 != null) conn1.close();
if (conn2 != null) conn2.close();
System.out.println("Resources closed!");
} catch (SQLException e) {
e.printStackTrace();
}
}
无论我如何修改数据库时区设置,这段Java代码输出的结果始终是Asia/Shanghai。
我在psql中看到的情况
如果我用psql连接:
youyou=> show timezone;
TimeZone
----------
UTC
(1 row)
youyou=> select now();
now
-------------------------------
2026-02-25 02:17:23.056023+00
(1 row)
并且
youyou=> show timezone;
TimeZone
---------------
Asia/Shanghai
(1 row)
youyou=> select now();
now
-------------------------------
2026-02-25 10:18:05.671536+08
(1 row)
psql的行为符合预期。
在Java中看到的情况
在同一数据库下,当我在两种配置(DB时区 = UTC,DB时区 = Asia/Shanghai)下运行我的Java代码时,输出始终为:
Connected!
Query Result: 2026-02-25 10:19:03.137973+08
Resources closed!
Connected!
Query Result: 2026-02-25 10:19:51.019322+08
Resources closed!
因此通过JDBC,SELECT now() 总是返回+08,即使psql的 show timezone显示为UTC。
我的问题
- 为什么JDBC总是给我Asia/Shanghai时区,即使数据库时区设置为UTC,且psql显示UTC?
- 在应用代码中控制这一点的推荐/优雅做法是什么?例如:
- 我应该在获得连接后显式设置会话时区吗?
- 还是应该在JDBC URL中传递一个时区参数? 对PostgreSQL / PolarDB + JDBC如何处理时区,以及如何在我的Java应用中获得一致的UTC时间戳,若能给出详细解释,将不胜感激。
解决方案
The timezone 参数不是数据库时区,而是会话时区。数据库服务器上的设置(在 postgresql.conf 中)只是会话时区的默认值。其思路是每个数据库客户端都应将 timezone 设置为合适的值——毕竟不同的客户端可能处在不同的时区。
JDBC驱动程序将会话时区设置为 JVM的默认时区,因此你要么修改它,要么在你的数据库会话中显式地 SET timezone。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。