タイムゾーンを認識する必要がある Java アプリがあります。Unix エポック時間を取得し、それをタイムスタンプに変換して Oracle SQL 呼び出しに使用しようとすると、正しいタイムゾーンが取得されますが、タイムゾーンの「useDaylightTime」値が正しくありません。つまり、現在「true」を返しています。 、私たちが DST にいないとき (私は TZ "America/New_York" のフロリダにいます)。
これは Red Hat Linux Enterprise 6 で実行されており、私が知る限り、タイムゾーンが正しく設定されています。たとえば、'date' は次のように返します。
また、「zdump」ユーティリティを使用して、「isdst」の現在の値が 0 であることも確認できます。
私の Java バージョンは 1.6.0_31 です。
私はこれをグーグルで検索し、これが引き起こした多くの問題を見てきましたが、それらの多くは単純に TZ を手動で設定するように言っていますが、私の問題は TZ ではなく、デフォルトの TZ の「isDaylight」が「true」に設定されているという事実です。 . これにより、クエリが 1 時間ずれたデータを返すようになっていると思います (そうであることがわかります)。
可能な限り簡単な方法でこれを再現するために実行した簡単なコードを次に示します。
public class TZdefault {
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis()/1000;
Calendar start = Calendar.getInstance();
start.setTimeInMillis(startTime);
start.setTimeZone(TimeZone.getDefault());
System.out.println("Start UTC: " + start + "ms: " + start.getTimeInMillis());
System.out.println("use daylight: " + start.getTimeZone().useDaylightTime());
} // end main
} // end class
最後に 1 つ。コードで TZ を「EST」に設定すると、もちろん、「isDaylight」が False に設定された TZ が返されます。しかし、それは良い解決策ではありません。
隠したいと思っていた詳細を追加したかったのです。
TIMEZONE フィールドで TIMESTAMP を使用する Oracle 11g データベースにレコードがあります。2 つのパラメータが BETWEEN 開始タイムスタンプと終了タイムスタンプを使用している JDBC クエリを実行しているだけです。
このテーブルにクエリを実行するとき、カレンダー エントリを使用する準備済みステートメントを使用しています。その唯一の目的は、タイムゾーンを操作することでした。肝心なのは、「デフォルト」のタイムゾーンが適用された後、開始時間と終了時間に「getTimeInMillis」メソッドを使用して pstmt.setTimestamp() 呼び出しを行っていることです。ログ出力は、実際には正しいミリ秒を入れていることを示していますが、返された SQL 結果は明らかに正確に 1 時間ずれています!
データ挿入側にも問題がないか検証中です。
しかし、多くのデバッグ情報があり、JDBC クエリで正しい時刻を要求しているようです。