Localize a string from MonthDay or YearMonth classes in java.time?

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

Standard formats may not be suitable for presentation to people. Is there a way to generate an automatically localized string to represent values ​​in either MonthDay or YearMonth ?

For example, in the United States, users may typically need MM / DD for the month and MM / YY for the year-month. While in the UK, users may need DD / MM for a month.

In any case, to automate such Locale changes, rather than explicitly defining formatting patterns?


I tried the following code using a date oriented format.

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

This code crashes, causing an exception when used for 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
source share
1 answer

See JDK-8168532 . JDK requires improvement.

You can work outside of the JDK, but that’s a lot of work. You must parse the CLDR XML files (which are interconnected and have many links). Then you retrieve the appropriate localized templates for MonthYear and YearMonth . You can then use these templates to create a DateTimeFormatter .

Alternatively, you can hard copy the map - Map<Locale, DateTimeFormatter> - based on the needs of your business.

+2
source

All Articles