2014-10-02 3 views
6

Я столкнулся с какой-то странной проблемой при тестировании моего метода и, похоже, смог получить конкретный пример моей проблемы.LocalDate и DateTimeFormatter не работают корректно с японской локалью

Я использую локаль ja_JP_JP_#u-ca-japanese, не способную анализировать дату, используя собственный шаблон даты, определенный локали.

Мне интересно, я делаю что-то неправильно или если это ошибка JDK.

Пожалуйста, обратите внимание, что для того, чтобы построить ja_JP_JP_#u-ca-japanese, вам нужно использовать new Locale("ja", "JP", "JP") согласно выписке из the Locale javadoc:

Особые случаи

Из соображений совместимости, два не соответствующие требованиям локали рассматриваются как особые случаи , Это ja_JP_JP и th_TH_TH. Они плохо сформированы в BCP 47, поскольку варианты слишком коротки. Чтобы облегчить переход на BCP 47, они обрабатываются специально во время строительства. Эти два случая (и только они) заставляют конструктор генерировать расширение, все остальные значения ведут себя точно так же, как и до Java 7.

Java использовал ja_JP_JP для представления японского языка, как используется в Японии, вместе с японским императорским календарем , Теперь это можно представить с использованием расширения локали Unicode, указав ключ локали Unicode ca (для «calendar») и введите japanese. Когда вызывается конструктор Locale с аргументами «ja», «JP», «JP», автоматически добавляется расширение «u-ca-japanese».

Java использовал th_TH_TH для представления тайского языка, который используется в Таиланде вместе с тайскими цифрами. Это также теперь можно представить с помощью расширения локали Unicode, указав ключ локали Unicode nu (для «number») и значение thai. Когда вызывается конструктор 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

Круглое способность расцепления делает работу, но ему нужны все данные, которые должны быть доступны.

В первом случае, необходимо указать как Locale и хронологию с использованием 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); 

То же самое можно сказать и о втором случае, когда с помощью ofPattern() замки локаль , но не хронология:

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

только когда оба локаль и хронология доступны и будут использованы круглые отключения возможно. Ваша проблема основана на попытке форматирования с использованием японского языка, но непоследовательно применяется японская хронология.

Смежные вопросы