Локализуйте строку из классов `MonthDay` или`YearMonth` в java.time?
Классы java.time, встроенные в Java 8 и более поздние версии, предлагают MonthDay
а также YearMonth
классы. Их toString
а также parse
методы используют стандартные форматы ISO 8601 (--MM-DD
& YYYY-MM
), что разумно.
Для представления людям стандартные форматы могут не подходить. Есть ли в любом случае генерировать автоматически локализованную строку для представления значений в объектах либо MonthDay
или же YearMonth
?
Например, в Соединенных Штатах пользователи, как правило, хотят, чтобы ММ / ДД означали день месяца, а ММ / ГГ - год-месяц. В то время как в Великобритании пользователи могут хотеть ДД / ММ в течение дня месяца.
Во всяком случае, чтобы автоматизировать такие изменения с помощью Locale
а не явно определять шаблоны форматирования?
Я попробовал следующий код, используя форматировщик, ориентированный на дату.
Locale l = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate ( FormatStyle.SHORT ).withLocale ( l );
YearMonth ym = YearMonth.of ( 2017 , Month.JANUARY );
MonthDay md = MonthDay.of ( Month.JANUARY , 29 );
String outputYm = ym.format ( f );
String outputMd = md.format ( f );
Этот код завершается ошибкой, вызывая исключение при использовании для YearMonth
или же MonthDay
,
За YearMonth
:
Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfMonth
at java.time.YearMonth.getLong(YearMonth.java:494)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2540)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
at java.time.format.DateTimeFormatterBuilder$LocalizedPrinterParser.format(DateTimeFormatterBuilder.java:4347)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720)
at java.time.YearMonth.format(YearMonth.java:1073)
at javatimestuff.App.doIt(App.java:56)
at javatimestuff.App.main(App.java:45)
За MonthDay
:
Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra
at java.time.MonthDay.getLong(MonthDay.java:451)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2540)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
at java.time.format.DateTimeFormatterBuilder$LocalizedPrinterParser.format(DateTimeFormatterBuilder.java:4347)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720)
at java.time.MonthDay.format(MonthDay.java:646)
at javatimestuff.App.doIt(App.java:57)
at javatimestuff.App.main(App.java:45)
1 ответ
См. JDK-8168532. В JDK требуется усовершенствование, чтобы сделать это легко.
Можно делать работу вне JDK, но это много работы. Вы должны проанализировать XML-файлы CLDR (которые связаны между собой и имеют много ссылок). Затем вы извлекаете соответствующие локализованные шаблоны для MonthYear
а также YearMonth
Затем эти шаблоны могут быть использованы для создания DateTimeFormatter
,
Кроме того, вы можете жестко закодировать карту - Map<Locale, DateTimeFormatter>
- исходя из потребностей вашего бизнеса.