提问者:小点点

如何强制LocalDateTime月为3个字母长


我的目标是使用LocalDateTime并显示一个月,正好有3个字母。

对于英语,这很容易:

val englishFormatter = DateTimeFormatter.ofPattern("MMM", Locale.ENGLISH)

for (month in 1..12) {
    println(LocalDateTime.of(0, month, 1, 0, 0)
                         .format(englishFormatter))
}

结果如预期:

Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec

对于德语(如上,仅使用Locale. GERMAN),结果出乎意料:

Jan. Feb. März Apr. Mai Juni Juli Aug. Sep. Okt. Nov. Dez.

虽然缩写在德语中很常见,但“März”、“Juni”和“Juli”并没有缩短(“Mai”不需要缩短)。此外,大多数月份包含超过3个字母(注意点!)

有没有办法缩短这些,两个?
e. g.

3月喜好3月
6月喜好6月喜好7月喜好7月。

顺便说一句:代码是静态编程语言,但静态编程语言使用的是Java的LocalDateTime。因此标记Java

编辑:我正在Android 7.0上运行此代码


共2个答案

匿名用户

准确控制Java给你的月份缩写很难,我想你不会想麻烦的。Java从最多四个来源获取语言环境数据,这些来源通常有版本。因此,即使你设法得到了完全正确的结果,它们在下一个Java版本中可能会有所不同。我建议你在两个选项中进行选择:

  1. 接受你所得到的。这是经过精心设计的,并非不合理的。任何德国人在阅读和理解你提到的缩写时会有任何困难吗?
  2. 如果您对缩写有非常具体的要求,例如MRZ而不是Mär,请对您需要的缩写进行硬编码,然后您知道无论语言环境提供者和/或语言环境数据版本是否发生变化,它们都会保持这种状态。

作为两者之间的折衷,您可以尝试通过定义系统属性java. locale.提供者来选择语言环境数据提供者。正如我所说,您从提供者那里获得的语言环境数据可能会在未来的版本中发生变化。

如果你想硬编码你自己喜欢的缩写,你仍然可以构建一个使用你的缩写的DateTimeFor物质。对于Java中的简单演示:

    Map<Long, String> monthAbbreviations = Map.ofEntries(
            Map.entry(1L, "Jan"), Map.entry(2L, "Feb"), Map.entry(3L, "Mrz"),
            Map.entry(4L, "Apr"), Map.entry(5L, "Mai"), Map.entry(6L, "Jun"),
            Map.entry(7L, "Jul"), Map.entry(8L, "Aug"), Map.entry(9L, "Sep"),
            Map.entry(10L, "Okt"), Map.entry(11L, "Nov"), Map.entry(12L, "Dez"));
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendText(ChronoField.MONTH_OF_YEAR, monthAbbreviations)
            .toFormatter(Locale.GERMAN);
    
    String allAbbreviations = Arrays.stream(Month.values())
            .map(formatter::format)
            .collect(Collectors.joining(" "));
    System.out.println(allAbbreviations);

输出是:

1月2月4月麦俊7月8月9月OK 11月12日

语言环境数据提供程序是,从LocaleServiceProvider的留档:

Java运行时环境提供以下四个区域设置提供程序:

  • "CLDR":基于Unicode联盟CLDR项目的提供商。
  • "COMPAT":表示与JDK8之前的JDK版本兼容的区域设置敏感服务(与JDK8的"JRE"相同)。
  • "SPI":表示实现此LocaleServiceProvider类的子类的语言环境敏感服务。
  • "HOST":在底层操作系统中反映用户自定义设置的提供程序。此提供程序可能不可用,具体取决于Java运行时环境实现。
  • "JRE":表示"COMPAT"的同义词。此名称已弃用,将在JDK的未来版本中删除。
  • 关于德语月份名称和语言环境数据源的问题:带有德语语言环境的SimpleDateFormat-Java8 vsJava10
  • LocaleServiceProvider
  • 的文档

匿名用户

您可以使用如下所需/预期的缩写:

import java.time.LocalDateTime
import java.time.Month
import java.time.format.TextStyle
import java.util.Locale

fun main() {
    for (m in 1..12) {
        val month = Month.of(m)
        println(month.getDisplayName(TextStyle.SHORT, Locale.GERMAN))
    }
}

输出为

Jan
Feb
Mär
Apr
Mai
Jun
Jul
Aug
Sep
Okt
Nov
Dez

LocalDateTime有一个方法getMonth(),它返回一个Month对象,这意味着您可以获取LocalDateTime的月份并构建所需的String,也许可以使用像下面这样的小乐趣

fun getAbbreviatedMonth(localDateTime: LocalDateTime, locale: Locale): String {
    return localDateTime.getMonth()
                        .getDisplayName(TextStyle.SHORT, locale)
}

或者甚至没有Locale作为参数和硬编码的Locale. GERMAN

我真的不知道为什么德语缩写被归结为4个字符,留下4个或更少字符的月份名称,并将其余的缩写为三个字母,后跟一个点,当你在系统上使用带有"MMM"模式的时,在静态编程语言Playground中,它没有!以下代码产生两行相等的输出:

import java.time.LocalDateTime
import java.time.Month
import java.time.format.TextStyle
import java.util.Locale
import java.time.format.DateTimeFormatter

fun main() {
    var localDateTime = LocalDateTime.now()
    println(getAbbreviatedMonth(localDateTime, Locale.GERMAN))
    println(localDateTime.format(DateTimeFormatter.ofPattern("MMM", Locale.GERMAN)))
}

fun getAbbreviatedMonth(localDateTime: LocalDateTime, locale: Locale): String {
    return localDateTime.getMonth()
                        .getDisplayName(TextStyle.SHORT, locale)
}

其中包括(2020-08-12执行)

Aug
Aug