2017-02-15 3 views
4

С ru locale возвращает полное название месяца (Февраль), но с en только номер (2).DateTimeFormatter не работает с шаблоном LLLL в en locale

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("LLLL", new Locale("ru")); 
LocalDate.now().format(formatter); 

MMMM работа с en, но не работает с ru (потребность в именительном падеже).

Как получить полное название месяца для всех мест?

+0

также проверьте это сообщение: http://stackoverflow.com/questions/30518954/datetimeformatter-month-pattern-letter-l-fails – 0x44656e6e795279616e

ответ

2

К сожалению the related bug issue JDK-8114833 пока не решен для Java-8. И мне пока не ясно, поддерживает ли Java-9 решение (и там дата завершения функции уже завершена). Таким образом, вы можете применить следующий обходной путь на основе своих знаний, какие языки нужен специальный автономный-форма (именительный) в течение нескольких месяцев, и которые не:

private static final Set<String> LANGUAGES_WITH_STANDALONE_CASE; 

static { 
    Set<String> set = new HashSet<>(); 
    set.add("ru"); 

    // add more languages which require LLLL-pattern (for example other slavish languages) 
    LANGUAGES_WITH_STANDALONE_CASE = Collections.unmodifiableSet(set); 
} 

public static void main(String[] args) throws Exception { 

    Locale locale = new Locale("en"); 

    DateTimeFormatter formatter = 
     DateTimeFormatter.ofPattern(
     LANGUAGES_WITH_STANDALONE_CASE.contains(locale.getLanguage()) 
      ? "LLLL" : "MMMM", 
     locale 
    ); 
    System.out.println(LocalDate.now().format(formatter)); 

    // ru => Февраль 
    // en => February 
} 

Я не могу сказать, что мне нравится это решение, потому что это требует дополнительных знаний, какие языки нужна эта схема. Но на самом деле это единственная возможность решить вашу проблему в рамках JSR-310 (aka java.time-API).

По тестированию теперь я вижу, что даже старый класс SimpleDateFormat (версия в Java-8) работает:

Locale locale = new Locale("en"); 

    SimpleDateFormat sdf = new SimpleDateFormat("LLLL", locale); 
    System.out.println(sdf.format(new Date())); 

Но это временное решение имеет сильный недостаток не работать с обычной календарной датой, но с java.util.Date только ,

Или вы можете добавить дополнительную зависимость к библиотеке, которая лучше поддерживает букву шаблона «L» и имеет лучший API-стиль и лучшие характеристики производительности. Например, вы можете использовать мою библиотеку Time4J. Вот демонстрация последнего случая, который также показывает, как независимый формат двигатель Time4J может быть использован для JSR-310-типов (также в разборе):

Locale locale = new Locale("ru"); 

    ChronoFormatter<LocalDate> formatter = 
     ChronoFormatter.ofPattern(
      "LLLL", 
      PatternType.CLDR, 
      locale, 
      PlainDate.axis(TemporalType.LOCAL_DATE) 
     ); 
    System.out.println(formatter.format(LocalDate.now())); 

    // ru => Февраль 
    // en => February 

Для лучшей производительности, я рекомендую лениво хранить форматировщик в ConcurrentHashMap для каждого региона.

0

Для падеже вы должны установить шаблон для ММ или LL вместо MMMM/LLLL

System.out.println(LocalDate.now().format(DateTimeFormatter.ofPattern("MM", new Locale("ru")))); 
System.out.println(LocalDate.now().format(DateTimeFormatter.ofPattern("MM", new Locale("en")))); 

что напечатает 02 для обоих районов

+1

Я думаю, что OP хочет полных имен, а не цифр. –

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