This question already has answers here:
How to format YearMonth and MonthDay depending on a Locale?

(3个答案)


2年前关闭。




我试图以一种不必指定顺序的方式来格式化 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"))));

前三份打印将按预期打印翻译的月份和日期,但始终为月份和日期。它不会更改顺序,因为我明确地告诉了它顺序。

接下来的两个(异常之前)将分别打印:
Aug 11, 2017
11 серп. 2017

请注意,取决于传递给该函数的语言环境,日期在月份之前还是之后。我如何用MonthDay对象执行此操作,因为用这种方法完成后,最后一行会引发异常。

最佳答案

到目前为止给出的其他答案描述了标准DateTimeFormatter的局限性,另请参见未解决的相关JDK-issue。通过删除“y”等来编辑本地化日期模式的建议解决方法非常棘手,并且由于该模式内还存在其他本地化文字,因此可能不适用于所有语言环境。

但是,您也可以考虑使用外部库,该库更加关注国际化问题,并且能够仅使用语言环境信息来格式化月日对象。因此,区域设置确定字段组成部分的顺序,还确定点,空格或其他特殊文字(如中文)的顺序。

这里有两个与系统时区相关的必要类型转换的选项:

ICU4J

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日

Time4J
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)的其他功能。

关于java - 使用DateTimeFormatter.ofLocalizedDate格式化MonthDay ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45684141/

10-12 21:48