3

GoogleとStackOverflowでTimeZoneとSimpleDateFormatに関する複数の投稿を行いましたが、それでも間違っていることがわかりません。私はいくつかのレガシーコードに取り組んでおり、間違った結果を与えるメソッドparseDateがあります。

使用しようとしているサンプルJUnitを添付して、問題を調査します。

最初のメソッド(testParseStrangeDate_IBM_IBM)は、IBMの実装を使用して、parseDateメソッドの出力をフォーマットします。Sunの実装で出力される2番目のフォーマット。

SunのSimpleDateFormatを使用すると、1時間異なる時間が得られます(これは夏時間に関連している可能性があります)。デフォルトのTimeZoneをIBMの実装に設定すると、parseDateメソッドが修正されます(setupDefaultTZメソッドの3行のコメントを解除するだけです)。

バグではないと思いますが、何か間違ったことをしています。

@Test
public void testParseStrangeDate_IBM_IBM() {
    setupDefaultTZ();

    Calendar date = parseDate("2010-03-14T02:25:00");
    com.ibm.icu.text.SimpleDateFormat dateFormat = new com.ibm.icu.text.SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    // PASSES:
    assertEquals("2010-03-14 02:25:00", dateFormat.format(date.getTime()));
}

@Test
public void testParseStrangeDate_SUN_SUN() {
    setupDefaultTZ();

    Calendar date = parseDate("2010-03-14T02:25:00");
    java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    // FAILS:
    assertEquals("2010-03-14 02:25:00", dateFormat.format(date.getTime()));
}

public static Calendar parseDate(String varDate) {
    Calendar cal = null;
    try {
        // DOES NOT MAKE ANY DIFFERENCE:
        // com.ibm.icu.text.SimpleDateFormat simpleDateFormat = new
        // com.ibm.icu.text.SimpleDateFormat(
        // "yyyy-MM-dd'T'HH:mm:ss");
        java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat(
                "yyyy-MM-dd'T'HH:mm:ss", Locale.US);
        Date date = simpleDateFormat.parse(varDate);
        cal = GregorianCalendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        System.out.println("CAL: [" + cal + "]");
    } catch (ParseException pe) {
        pe.printStackTrace();
    }
    return cal;
}

private void setupDefaultTZ() {
    java.util.TimeZone timeZoneSun = java.util.TimeZone.getTimeZone("America/Chicago");
    java.util.TimeZone.setDefault(timeZoneSun);

    // UNCOMMENTING THIS ONE FIXES SUN PARSING ??
    // com.ibm.icu.util.TimeZone timeZoneIbm = com.ibm.icu.util.TimeZone
    // .getTimeZone("America/Chicago");
    // com.ibm.icu.util.TimeZone.setDefault(timeZoneIbm);

    Locale.setDefault(Locale.US);
}
4

1 に答える 1

2

問題は、存在しない時間を指定したことです。午前 2 時が午前 3 時になり、午前 2 時 25 分になることはありません。

さて、ここで何が起こるかについては、さまざまなオプションがあります。Noda Timeでは、例外をスローすると思います (とにかくそれが計画です)。Joda Time (Date/Calendar/SimpleDateFormat よりもはるかに優れた Java API - 可能であれば移行を検討する必要があります) を使用すると、午前 3 時 25 分、つまり移行後 25 分が得られると思います。

DST 移行のために不可能な日付と時刻の組み合わせが与えられた場合、どうしたいですか? この状況では、「間違った」結果が何を意味するのかを確実に知ることは困難です。あなたの単体テストには多少の欠陥があると思います.その時間にフォーマットされるべき時間はありません.

IBM タイム ゾーンが「機能する」理由についての私の推測では、米国が DST 移行を変更する前の古いタイム ゾーン データを使用している可能性があります。3 月 28 日を使用してみてください。これは、そうでなければそうであったと私が思うときです。おそらく、IBM ゾーンでは同じようにテストが失敗することがわかりますが、Sun ゾーンではそうではありません:) (Sun ゾーンは考慮しないため)これは DST 移行です。)

于 2010-03-01T15:21:39.643 に答える