8

私は自分のシステムで単体テストが失敗している既存のコードをデバッグしていますが、同僚のシステムでは失敗していません。根本的な原因は、解析可能であるはずの日付を解析するときにSimpleDateFormatがParseExceptionsをスローしていることです。システムで失敗しているコードを示す単体テストを作成しました。

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import junit.framework.TestCase;

public class FormatsTest extends TestCase {

    public void testParse() throws ParseException {
        DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
        formatter.setTimeZone(TimeZone.getDefault());
        formatter.setLenient(false);

        formatter.parse(formatter.format(new Date()));
    }
}

このテストは私のシステムでParseExceptionをスローしますが、他のシステムでは正常に実行されます。

java.text.ParseException: Unparseable date: "20100603100243.118 -0600"
    at java.text.DateFormat.parse(DateFormat.java:352)
    at FormatsTest.testParse(FormatsTest.java:16)

私はできることを発見しました、setLenient(true)そして、テストは成功するでしょう。これsetLenient(false)は、このテストが模倣する製品コードで使用されているものなので、変更したくありません。

4

3 に答える 3

6

--- 開発者が IBM の J9 1.5.0 Java 仮想マシンを使用していることを示す応答後に編集 ---

IBM の J9 JVM には、DateFormat のサブクラスであるため、SimpleDateFormat が継承する可能性が高い DateFormat の解析ルーチンにいくつかのバグと非互換性があるようです。IBM の J9 が他の JVM (Sun の HotSpot JVM など) とはまったく異なる方法で機能していることを裏付けるいくつかの証拠は、こちらで見ることができます。

これらのバグと非互換性は、J9 JVM 内でさえ一貫していないことに注意してください。つまり、IBM J9 フォーマット ロジックは、IBM J9 解析ロジックと互換性のないフォーマットされた時刻を実際に生成する可能性があります。

IBM の J9 JVM に縛られている人は、DateFormat.parse(...) (または SimpleDateFormat.parse(...)) を使用しないことで、JVM のバグを回避する傾向があるようです。代わりに、 java.util.regex.Matcher を使用してフィールドを手動で解析する傾向があります。

J9 JVM の今後のリリースで問題が修正される可能性がありますが、修正されない可能性もあります。

--- 元の投稿に続く ---

面白いことに、同じコードを次のように変更しました。

import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;

public class FormatsTest {

 public void testParse() throws ParseException {
  DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
  formatter.setTimeZone(TimeZone.getDefault());
  formatter.setLenient(false);
  System.out.println(formatter.format(new Date()));

  formatter.parse(formatter.format(new Date()));
 }

 public static void main(String[] args) throws Exception {
   FormatsTest test = new FormatsTest();
   test.testParse();
 }

}

私のシステムでは問題なく動作します。私はそれがあなたの環境にあることに賭けます。ある JVM メジャー リリースでコードをコンパイルして別のメジャー リリースで実行している (ライブラリが古くなっている可能性があるため、問題が発生する可能性があります) か、それを実行しているシステムがタイム ゾーン情報を奇妙に報告している可能性があります。

最後に、JVM の非常に初期のポイント リリースを使用しているかどうかを検討することをお勧めします。バグがさまざまなバージョンに忍び寄る場合があり、それらは後のポイント リリースで修正されます。システムの「java -version」情報を含めるように質問を修正していただけますか?

いずれにせよ、これらはどちらも経験に基づいた推測にすぎません。コードは記述どおりに機能するはずです。

于 2010-06-03T16:06:53.237 に答える
1

これはおそらく、SimpleDateFormatクラスに関するIBMのJ9VMのバグであるはずです。

この投稿は同様の問題を示しており、v6で修正する必要があると述べています。

いくつかのリリースの変更点のリストはここにあります

DateFormatに関連する番号があるようです。したがって、パッチを提供するために、IBMにバグレポートなどを提出する必要があります。

于 2010-06-03T16:31:51.327 に答える
0

お使いのコンピューターとリモート コンピューターの LANG 環境変数を確認します。

日付はロケールに従って解析されるため、「7 月」は LANG が英語に設定されている場合にのみ 7 月として機能し、それ以外の場合は ParseException が発生します。

プログラムを実行してから実行することで、簡単なテストを行うことができexport LANG="en_US.UTF-8"ます。

次のメソッドを使用して、プログラムでロケールを設定することもできます。 DateFormat.getDateInstance(int, java.util.Locale)

于 2011-08-04T14:17:00.363 に答える