7

このような2つの日付を比較するmysqlにクエリがあります

convert_tz(updatedDate,'+05:30','-05:00') < ?

convert 関数は、列 createddate の値を米国時間で返します。このクエリをmysqlクエリブラウザで実行すると

convert_tz(updatedDate,'+05:30','-05:00') < '2013-04-14 09:30:00'

たとえば、正しい値が得られます

product    count
-------    ------
    A        123
    B        7

今、私はこのようにPreparedStatementを使用してJavaでこれを設定しています

pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));

                rs=pst.executeQuery();
                System.out.println("=====new Open Tickets Query executed=====");
                System.out.println(pst);

最後の行はクエリ全体を出力し、値セットは次のとおりです。

convert_tz(updatedDate,'+05:30','-05:00') < '2013-04-14 09:30:00'

しかし、それは私にこのような異なる値を与えます

product    count
-------    ------
    A        155
    B        19

だから、コードを変更したのはTimeZoneの問題だと思った

end.setTimeZone(TimeZone.getTimeZone("America/New York"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));

                rs=pst.executeQuery();
                System.out.println("=====new Open Tickets Query executed=====");
                System.out.println(pst);

しかし、それでも同じ間違った結果が得られます。

詳細: カレンダー終了変数の設定方法

日付文字列「2013-04-14 09:30:00」を提供するWebアプリケーションがあります

            DateFormat df1=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                Calendar end=Calendar.getInstance();
                end.setTime(df1.parse(endString));
                end.set(Calendar.HOUR, 9);
                end.set(Calendar.MINUTE, 30);
                end.set(Calendar.SECOND, 0);

また、私が java.util.Date オブジェクトで試した実験では、コードに続く正しい結果が得られます

SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
end.setTime(sdf.parse("2012-10-01 00:00:00"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTime()));

更新:- 非推奨の方法を使用すると、答えは正しいです

 pst.setTimestamp(1, new java.sql.Timestamp(octDate.get(Calendar.YEAR)-1900,octDate.get(Calendar.MONTH),octDate.get(Calendar.DATE),octDate.get(Calendar.HOUR),octDate.get(Calendar.MINUTE),octDate.get(Calendar.SECOND),0));
pst.setTimestamp(2, new java.sql.Timestamp(end.get(Calendar.YEAR)-1900,end.get(Calendar.MONTH),end.get(Calendar.DATE),end.get(Calendar.HOUR),end.get(Calendar.MINUTE),end.get(Calendar.SECOND),0));

更新 2:- 最初の回答の提案の後、私はこれを行いました

1)SELECT NOW()mysqlで実行され、返されました'2013-04-22 11:56:08'

2) 実行

System.out.println(new Date(System.currentTimeMillis()));

出力:Mon Apr 22 11:56:25 IST 2013

両方のシステムが同じタイムゾーンを持っていることを意味します

4

5 に答える 5

6

背景: 優秀なプログラマーでさえ共有する驚くほど一般的な (そして大きな) 誤解は、タイム スタンプ (データベース、日付、カレンダー、タイムスタンプなど) にタイム ゾーン情報が保存されているという考えです。彼らはしない。 タイムスタンプ (とにかく Java 8 まで) は、UTC 1970 年 1 月 1 日の午前 0 時からのミリ秒数として格納されます。文の終わり。タイム ゾーンを設定する唯一のことは、そのタイム スタンプを人間が読める形式に変換するのに十分な情報をコンピューターに提供することです。

回答: これがタイム ゾーンの問題であると疑ったとき、あなたは正しかった. しかし、これを検証するために使用したコードにも問題があります。

end.setTimeZone(TimeZone.getTimeZone("America/New York"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));

時刻はすでに設定されているため、このsetTimeZoneステートメントはに格納されている時刻には影響しません。end後で時間を保存した場合にのみ効果があり、人間が読める形式から時間を変換する Calendar のメソッドの 1 つを使用した場合にのみ効果がありました (そして ではありませんsetTimeInMillis)。

タイムスタンプを準備済みステートメントに渡すために使用getTimeInMillisする場合、タイムスタンプを直接取得しています。人間の形式に変換していないため、タイムゾーン情報は無視されます。

試してみると

SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
end.setTime(sdf.parse("2012-10-01 00:00:00"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTime()));

pst.setTimestamp(1, new java.sql.Timestamp(octDate.get(Calendar.YEAR)-1900,octDate.get(Calendar.MONTH),octDate.get(Calendar.DATE),octDate.get(Calendar.HOUR),octDate.get(Calendar.MINUTE),octDate.get(Calendar.SECOND),0));
pst.setTimestamp(2, new java.sql.Timestamp(end.get(Calendar.YEAR)-1900,end.get(Calendar.MONTH),end.get(Calendar.DATE),end.get(Calendar.HOUR),end.get(Calendar.MINUTE),end.get(Calendar.SECOND),0));

人間が読める形式に/から変換するメソッドを使用しているため、動作しているように見えます。したがって、指定されたタイムゾーン情報が使用されますただし、これは実際の問題を隠蔽しているだけです。本当の問題は、 から解析したときに時刻が不適切に変換されたことですendString。つまり、で表現されたタイム ゾーンは、日付が解析された時点でendString設定されたタイム ゾーンと一致しません。df1

短い答え: この行の前:

end.setTime(df1.parse(endString));

必要がある:

  • 時刻がどのタイムゾーンでendString表現されているかを調べます。
  • 同じタイムゾーンに設定df1ないでください。 endは人間の形式から日付を変換するものであるためdf1、使用されるのはそのタイムゾーン情報です。

乾杯!

于 2013-04-26T23:12:25.473 に答える