Stephen C. 写了一个很好地涵盖了您的选择的答案。作为补充,因为我同意选项 2 和 5 是最正确的,所以我想把这两个拼写出来。
选项 2:使用不同的格式
大多数可用语言环境的本地化日期格式都内置在 Java 中。这些通常使用不足。如果依靠 Java 知道如何为我们的受众和他们的语言环境设置日期格式,我们可以为自己节省很多时间。我以德语为例,因为它是在日期部分和缩写之间始终包含点的语言环境之一。以下内容也适用于您的语言环境,即使它不是德语(如果您替换 Locale.getDefault(Locale.Category.FORMAT) 或您用户的语言环境)。
private static final Locale LOCALE = Locale.GERMAN;
private static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(LOCALE);
为了演示,我正在格式化当年每个月的一天:
LocalDate date = LocalDate.of(2021, Month.JANUARY, 16);
for (int i = 0; i < 12; i++) {
System.out.println(date.format(DATE_FORMATTER));
date = date.plusMonths(1).minusDays(1);
}
输出是:
16.01.2021
15.02.2021
14.03.2021
13.04.2021
12.05.2021
11.06.2021
10.07.2021
09.08.2021
08.09.2021
07.10.2021
06.11.2021
05.12.2021
对于德语语言环境,我们在这里得到数字月份。其他语言环境可能会给出其他结果,例如月份缩写。
如果您想要不使用数字月份的较长格式,请指定例如 FormatStyle.LONG 而不是 FormatStyle.MEDIUM:
private static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)
.withLocale(LOCALE);
16. Januar 2021
15. Februar 2021
14. März 2021
13. April 2021
12. Mai 2021
11. Juni 2021
10. Juli 2021
9. August 2021
8. September 2021
7. Oktober 2021
6. November 2021
5. Dezember 2021
我建议您的用户对上述其中一项感到满意。
选项 5:DateTimeFormatterBuilder.appendText(TemporalField, Map)
如果您的用户告诉您他们不想要上面的本地化格式,并且他们确实想要带有月份缩写和单点的格式 - 它会越来越长,但结果很漂亮,每个人都会很高兴。
private static final DateTimeFormatter DATE_FORMATTER = new DateTimeFormatterBuilder()
.appendPattern("dd.")
.appendText(ChronoField.MONTH_OF_YEAR, getMonthAbbreviations())
.appendPattern(".uuuu")
.toFormatter(LOCALE);
private static Map<Long, String> getMonthAbbreviations() {
return Arrays.stream(Month.values())
.collect(Collectors.toMap(m -> Long.valueOf(m.getValue()),
MyClass::getDisplayNameWithoutDot));
}
private static String getDisplayNameWithoutDot(Month m) {
return m.getDisplayName(TextStyle.SHORT, LOCALE)
.replaceFirst("\\.$", "");
}
来自与上述相同循环的输出:
16.Jan.2021
15.Feb.2021
14.März.2021
13.Apr.2021
12.Mai.2021
11.Juni.2021
10.Juli.2021
09.Aug.2021
08.Sep.2021
07.Okt.2021
06.Nov.2021
05.Dez.2021
每次一个点。核心技巧是使用 Java 的月份缩写,如果有一个点(Jan. 变为 Jan),则从其中删除点,如果没有点则按原样使用它(Mai 保持 Mai)。我的getDisplayNameWithoutDot 方法就是这样做的。我反过来使用这种方法来构建两个参数appendText(TemporalField, Map<Long, String>) 方法需要并用于格式化的映射。