在 java.time 中本地化来自 `MonthDay` 或 `YearMonth` 类 的字符串?
Localize string from `MonthDay` or `YearMonth` classes in java.time?
java.time 类 内置于 Java 8 和更高版本中,提供 MonthDay
和 YearMonth
类。他们的 toString
和 parse
方法使用标准的 ISO 8601 格式(--MM-DD
& YYYY-MM
),这是明智的。
为了向人类展示,标准格式可能不适合。无论如何生成一个自动本地化的字符串来表示 MonthDay
或 YearMonth
对象中的值?
例如,在美国,用户通常可能希望 MM/DD 代表月-日,MM/YY 代表年-月。在英国,用户可能希望 DD/MM 表示月-日。
是否要通过 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)
参见JDK-8168532。 JDK 中需要增强功能以简化此操作。
可以在 JDK 之外完成工作,但工作量很大。您必须解析 CLDR XML 文件(这些文件相互关联并且有很多参考)。然后提取 MonthYear
和 YearMonth
的相关本地化模式,然后这些模式可用于创建 DateTimeFormatter
.
或者,您可以根据业务需要对地图进行硬编码 - Map<Locale, DateTimeFormatter>
。
java.time 类 内置于 Java 8 和更高版本中,提供 MonthDay
和 YearMonth
类。他们的 toString
和 parse
方法使用标准的 ISO 8601 格式(--MM-DD
& YYYY-MM
),这是明智的。
为了向人类展示,标准格式可能不适合。无论如何生成一个自动本地化的字符串来表示 MonthDay
或 YearMonth
对象中的值?
例如,在美国,用户通常可能希望 MM/DD 代表月-日,MM/YY 代表年-月。在英国,用户可能希望 DD/MM 表示月-日。
是否要通过 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)
参见JDK-8168532。 JDK 中需要增强功能以简化此操作。
可以在 JDK 之外完成工作,但工作量很大。您必须解析 CLDR XML 文件(这些文件相互关联并且有很多参考)。然后提取 MonthYear
和 YearMonth
的相关本地化模式,然后这些模式可用于创建 DateTimeFormatter
.
或者,您可以根据业务需要对地图进行硬编码 - Map<Locale, DateTimeFormatter>
。