我正在尝试格式化 MonthDay
对象以一种我不必指定顺序的方式。我正在尝试使用本地化的 DateTimeFormatter
.
我有这个代码:
LocalDate datetime = LocalDate.parse("2017-08-11", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
MonthDay monthday = MonthDay.from(datetime);
System.out.println(monthday.format(DateTimeFormatter.ofPattern("MMMM dd").withLocale(Locale.ENGLISH)));
System.out.println(monthday.format(DateTimeFormatter.ofPattern("MMMM dd").withLocale(Locale.GERMANY)));
System.out.println(monthday.format(DateTimeFormatter.ofPattern("MMMM dd").withLocale(Locale.forLanguageTag("UK"))));
System.out.println(datetime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.ENGLISH)));
System.out.println(datetime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.forLanguageTag("UK"))));
// next line throws exception for java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra
System.out.println(monthday.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.forLanguageTag("UK"))));
前 3 次打印将按预期打印翻译后的月份和日期,但始终是先是月份再是日期。它不会更改顺序,因为我明确告诉它顺序。
接下来的两个(异常之前)将分别打印:
Aug 11, 2017
11 серп. 2017
请注意日期是在月份之前还是之后,具体取决于传递给函数的语言环境。我如何使用 MonthDay
对象执行此操作,因为最后一行在以这种方式完成时抛出异常。
目前给出的其他答案描述了标准DateTimeFormatter
的局限性,另见 Unresolved 相关JDK-issue .建议的通过删除“y”等来编辑本地化日期模式的解决方法很棘手,并且可能不适用于所有语言环境,因为模式中存在其他本地化文字。
但是,您也可以考虑使用更加关注国际化问题的外部库,并且能够仅使用语言环境信息来格式化月-日对象。因此,语言环境决定了字段组件以及点、空格或其他特殊文字(如中文)的顺序。
这里有两个选项,其中包含与您的系统时区相关的必要类型转换:
MonthDay md = MonthDay.now();
GregorianCalendar gcal =
new GregorianCalendar(
2000, // avoids possible leap year problems
md.getMonthValue() - 1,
md.getDayOfMonth()
);
DateFormat df =
DateFormat.getInstanceForSkeleton(
DateFormat.ABBR_MONTH_DAY,
Locale.forLanguageTag("en")
);
System.out.println(df.format(gcal.getTime())); // Aug 15
DateFormat df2 =
DateFormat.getInstanceForSkeleton(
DateFormat.ABBR_MONTH_DAY,
Locale.forLanguageTag("de")
);
System.out.println(df2.format(gcal.getTime())); // 15. Aug.
DateFormat df3 =
DateFormat.getInstanceForSkeleton(DateFormat.MONTH_DAY, Locale.forLanguageTag("zh"));
System.out.println(df3.format(gcal.getTime())); // 8月15日
MonthDay md = MonthDay.now();
ChronoFormatter<AnnualDate> cf1 =
ChronoFormatter.ofStyle(DisplayMode.SHORT, Locale.GERMAN, AnnualDate.chronology());
System.out.println(cf1.format(AnnualDate.from(md))); // 15.8.
ChronoFormatter<AnnualDate> cf2 =
ChronoFormatter.ofStyle(DisplayMode.MEDIUM, Locale.GERMAN, AnnualDate.chronology());
System.out.println(cf2.format(AnnualDate.from(md))); // 15.08.
ChronoFormatter<AnnualDate> cf3 =
ChronoFormatter.ofStyle(DisplayMode.LONG, Locale.ENGLISH, AnnualDate.chronology());
System.out.println(cf3.format(AnnualDate.from(md))); // Aug 15
ChronoFormatter<AnnualDate> cf4 =
ChronoFormatter.ofStyle(DisplayMode.FULL, Locale.GERMAN, AnnualDate.chronology());
System.out.println(cf4.format(AnnualDate.from(md))); // 15. August
ChronoFormatter<AnnualDate> cf5 =
ChronoFormatter.ofStyle(DisplayMode.FULL, Locale.CHINESE, AnnualDate.chronology());
System.out.println(cf5.format(AnnualDate.from(md))); // 8月15日
免责声明:Time4J 是我自己编写的,用于填补空白或改进 JSR-310 (java.time-package) 的其他功能。