Localize string from `MonthDay` or `YearMonth` classes in java.time? [duplicate]

别说谁变了你拦得住时间么 提交于 2020-01-03 02:52:00

问题


The java.time classes built into Java 8 and later offer the MonthDay and YearMonth classes. Their toString and parse methods use standard ISO 8601 formats (--MM-DD & YYYY-MM), which is wise.

For presentation to humans, the standard formats may not be suitable. Is there anyway to generate an automatically localized string to represent the values in objects of either MonthDay or YearMonth?

For example, in the United States users might typically want MM/DD for month-day and MM/YY for year-month. While in the UK users might want DD/MM for month-day.

Anyway to automate such variations by Locale rather than explicitly define formatting patterns?


I tried the following code, using a date-oriented localizing formatter.

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 );

That code fails, throwing an exception when used for either YearMonth or MonthDay.

For 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)

For 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:


See JDK-8168532. There needs an enhancement in the JDK to make this easy.

It is possible to do the work outside the JDK, but it is a lot of work. You have to parse the CLDR XML files (which are interlinked and have many references). Then you extract the relevant localized patterns for MonthYear and YearMonth, Then those patterns can be used to create a DateTimeFormatter.

Alternatively, you can hard code a map - Map<Locale, DateTimeFormatter> - based on your business needs.



来源:https://stackoverflow.com/questions/41841667/localize-string-from-monthday-or-yearmonth-classes-in-java-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!