【问题标题】:Localize string from `MonthDay` or `YearMonth` classes in java.time? [duplicate]在 java.time 中本地化来自“MonthDay”或“YearMonth”类的字符串? [复制]
【发布时间】:2017-01-25 00:54:55
【问题描述】:

Java 8 及更高版本中内置的 java.time 类提供 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)

【问题讨论】:

  • 大概你正在寻找与MonthDay.format(DateTimeFormatter)相关的东西?
  • @LouisWasserman 添加了代码以显示DateTimeFormatter.ofLocalizedDate 在format() 的format() 方法中失败MonthDay 和YearMonth。如果您有有效的变体,请发布。我想知道答案是否可能位于DateTimeFormatterBuilder,但我不知道如何。

标签: java date java-time 2-digit-year


【解决方案1】:

见JDK-8168532。需要在 JDK 中进行增强以简化此操作。

可以在 JDK 之外进行工作,但工作量很大。您必须解析 CLDR XML 文件(它们是相互关联的并且有很多引用)。然后你提取MonthYear和YearMonth的相关本地化模式,然后这些模式可以用来创建DateTimeFormatter。

或者,您可以根据您的业务需求对地图进行硬编码 - Map<Locale, DateTimeFormatter>。

【讨论】:

  • JDK-8168532 在 Java 10 中得到修复的可能性有多大?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多