发出以下 SQL 通过 PL/SQL、ODBC 和 JDBC 生成不同的结果:
select sysdate from dual
在 PL/SQL 或 ODBC 上运行它时,日期和时间是正确的。在 JDBC 上,它少了一个小时。似乎它没有考虑夏令时。
例如,在 PL/SQL 上结果是2012-11-05 16:53:53.0
,而在 JDBC 上是2012-11-05 15:53:53.0
.
它只发生在某些数据库上。更改数据库时区 ( select dbtimezone from dual
) 似乎不会影响结果。
该命令正在巴西执行。由于夏令时,原始 GMT 偏移量为 -03:00,当前偏移量为 -02:00。
客户端 JVM 的时区数据库是最新的。
要诊断数据库中的“错误”结果,只需打印结果:
((OracleResultSet) statement.executeQuery("select sysdate from dual")).getTIMESTAMP(1).toString();
Oracle 的TIMESTAMP
toString
方法不依赖于时区信息。JVM 的时区可能只会在创建 之前影响结果TIMESTAMP
,即在从网络读取并将其转换为 Java 表示时。
更改客户端和数据库服务器时间配置的测试:
SYSDATE
总是返回在数据库服务器中解析的日期/时间,客户端 JVM 的user.timezone
选项和客户端的机器时间配置无关紧要。- 另一方面,获取
SYSTIMESTAMP
是使用两个时区信息来解决的:看起来它以 UTC 从服务器获取日期和时间,然后在客户端应用时区以获取本地日期和时间。
客户端运行 Windows,服务器运行 Linux。
为了让事情变得更奇怪,也发出一个TO_CHAR
错误的结果:
select TO_CHAR(SYSDATE, 'DD/MM/YYYY HH24:MI:SS') from dual
- 直接在 Oracle 上:
06/11/2012, 10:38:49
- 在 Java 上:
06/11/2012 09:38:49
甲骨文服务器:
[root@oracle1 ~]# cat /etc/sysconfig/clock
ZONE="America/Sao_Paulo"
UTC=false
ARC=false
[root@oracle1 ~]# echo $TZ
[root@oracle1 ~]# date
Tue Nov 13 14:58:38 BRST 2012
[root@oracle1 ~]#
[root@oracle2 ~]# cat /etc/sysconfig/clock
ZONE="America/Sao_Paulo"
UTC=false
ARC=false
[root@oracle2 ~]# echo $TZ
[root@oracle2 ~]# date
Tue Nov 13 14:59:58 BRST 2012
[root@oracle2 ~]#
有什么想法吗?我应该从数据库中收集什么信息或配置来诊断和解决这个问题?