9

アプリケーションのバグを特定しようとしています。次の「なぞなぞ」の作成に成功しました。

SimpleDateFormat f1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
SimpleDateFormat f2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date d = f1.parse("2012-01-01T00:00:00+0700");
String s1 = f1.format(d); // 2011-12-31T18:00:00+0700
String s2 = f2.format(d); // 2011-12-31T18:00:00+0100

このコードを Android API 7 で実行すると、コメントに値が表示されます(はい、本当に)。この動作は、特定の Java 実装によって異なります。

私の質問は次のとおりです。

  • s1 が s2 と等しくないのはなぜですか?
  • さらに重要なのは、なぜ s1 が正しくないのでしょうか? s2適切な時点を指していますが、そうでs1はありません。Android の SimpleDateFormat 実装にバグがあるようです。

質問 1 への回答: BalusC による回答を参照してください。

  • [使用後SimpleDateFormat#parse] setTimeZone の呼び出しによって以前に設定された TimeZone 値は、以降の操作のために復元する必要がある場合があります。

質問 2 への回答: wrygiel (私自身) による回答を参照してください。

  • これは、Android 2.1 (API 7) のバグによるものです。
4

4 に答える 4

8

これは、次の javadoc に記載されていDateFormat#parse()ます。

指定された解析位置に従って日付/時刻文字列を解析します。たとえば、時刻のテキスト"07/10/96 4:5 PM, PDT"は、と同等の Date に解析されDate(837039900000L)ます。

デフォルトでは、解析は緩やかです。入力がこのオブジェクトの format メソッドで使用される形式ではないが、日付として解析できる場合、解析は成功します。クライアントは、 を呼び出すことにより、フォーマットへの厳密な順守を要求できsetLenient(false)ます。

この解析操作では、 を使用してcalendarを生成しDateます。その結果、サブクラスの実装によっては、calendar's日時フィールドとTimeZone値が上書きされた可能性があります。への呼び出しTimeZoneによって以前に設定された値はsetTimeZone、以降の操作のために復元する必要がある場合があります。

最後の段落に注意してください。残念ながら、これが正確にいつ発生するか説明されていません。特定の問題を解決するには、フォーマット操作の前に目的のタイムゾーンを明示的に設定する必要があります。

SimpleDateFormatそれ自体の可変性に関しては、これは何年も前から知られています。そのインスタンスを静的変数またはクラス変数として作成して割り当てることはできませんが、常にメソッド (スレッドローカル) 変数として使用してください。

于 2012-05-16T18:56:37.827 に答える
6

これは、Android 2.1 (API 7)のバグによるものです。Android プログラマーは、Android 2.1 の実装において、文書化されていない Java の動作(それ自体が修正不可能なバグに分類されます!) を見落としていたようです。

于 2012-05-16T20:09:27.843 に答える
0

あなたの質問に興味をそそられたので、先に進んであなたのコードをコンパイルしました。結果?予想通り...

2011-12-31T18:00:00+0100
2011-12-31T18:00:00+0100

2 つの値は同じです。同時実行性を使用していますか? たぶん、変数は.の直前に別のスレッドで変更されますf2.format(d).

于 2012-05-16T18:54:14.630 に答える
0

同じプログラムを実行して、s1 と s2 を比較してみました。彼らは私と同じように来ます。 ここに画像の説明を入力

于 2012-05-16T19:05:51.033 に答える