6

私の方法をテストしているときに奇妙な問題に遭遇しました。私の問題の具体的な例を得ることができたようです。

ja_JP_JP_#u-ca-japaneseロケールで定義された独自の日付パターンを使用して日付を解析できないロケールを使用しています。

何か間違ったことをしているのか、それとも JDK のバグなのか疑問に思っています。

を構築するには、Locale javadocからの抜粋に従ってja_JP_JP_#u-ca-japanese使用する必要があることに注意してください。new Locale("ja", "JP", "JP")

特殊なケース

互換性の理由から、2 つの非準拠ロケールは特別なケースとして扱われます。ja_JP_JP と th_TH_TH です。バリアントが短すぎるため、これらは BCP 47 では不適切な形式です。BCP 47 への移行を容易にするために、これらは構築中に特別に処理されます。これら 2 つのケース (およびこれらのみ) により、コンストラクターは拡張機能を生成し、他のすべての値は Java 7 より前とまったく同じように動作します。

Java では、ja_JP_JP を使用して、日本で使用されている日本語を和暦と共に表現しています。これは、Unicode ロケール キー ca ("calendar" の場合) を指定し、japanese と入力することで、Unicode ロケール拡張を使用して表現できるようになりました。Locale コンストラクターが引数「ja」、「JP」、「JP」で呼び出されると、拡張子「u-ca-japanese」が自動的に追加されます。

Java は th_TH_TH を使用して、タイで使用されるタイ語をタイ語の数字と一緒に表します。これは、Unicode ロケール キー nu (「数値」) と値 thai を指定することにより、Unicode ロケール拡張を使用して表現できるようになりました。Locale コンストラクターが引数「th」、「TH」、「TH」で呼び出されると、拡張子「u-nu-thai」が自動的に追加されます。

問題を示す特定のテスト ケース:

@Test
public void testJapaneseLocale() {
    LocalDate specificLocalDate = LocalDate.of(2014, 10, 2);
    Locale jpLocale = new Locale("ja", "JP", "JP");
    
    DateTimeFormatter jpDateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(jpLocale);
    String jpDate = specificLocalDate.format(jpDateTimeFormatter);
    
    String jpPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.SHORT, null, Chronology.ofLocale(jpLocale), jpLocale);
    LocalDate jpLocalDate = LocalDate.parse(jpDate, DateTimeFormatter.ofPattern(jpPattern, jpLocale));
    
    assertEquals(specificLocalDate, jpLocalDate);
}

このコードは、英語などの他の通常のロケールでも機能します。

4

1 に答える 1

4

ラウンド トリップ機能は機能しますが、すべてのデータを利用できるようにする必要があります。

最初のケースでは、および メソッドを使用して、ロケール年表の両方を指定する必要があります。withLocale()withChronology()

LocalDate date = LocalDate.of(2014, 10, 2);
Locale jpLocale = new Locale("ja", "JP", "JP");
Chronology chrono = Chronology.ofLocale(jpLocale);
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
        .withLocale(jpLocale)
        .withChronology(chrono);
String jpDateStr = date.format(f);
LocalDate result = LocalDate.parse(jpDateStr, f);

同じことが 2 番目のケースにも当てはまります。使用ofPattern()するとロケールがロックされますが、年表はロックされません。

String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
    FormatStyle.SHORT, null, chrono, jpLocale);
DateTimeFormatter f = DateTimeFormatter.ofPattern(pattern, jpLocale)
    .withChronology(chrono);
LocalDate jpLocalDate = LocalDate.parse(jpDateStr, f);

ロケールと暦の両方が利用可能で使用されている場合にのみ、往復が可能になります。あなたの問題は、日本語のロケールを使用してフォーマットしようとすることに基づいていますが、日本の年表を一貫して適用していません。

于 2014-10-08T22:33:28.813 に答える