次の SQL を発行すると、PL/SQL、ODBC、および JDBC を介して異なる結果が生成されます。
select sysdate from dual
PL/SQL または ODBC で実行すると、日付と時刻が正しくなります。JDBC では、1 時間短縮されます。サマータイムは考慮していないようです。
たとえば、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
Oracle サーバー:
[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 ~]#
何かご意見は?この問題を診断して解決するには、データベースからどの情報または構成を収集する必要がありますか?