如何在 Java 中以正确的语言环境顺序格式化日期和月份?
How can I format day and month in the locale-correct order in Java?
有没有办法按照 Java/Kotlin 中正确的语言环境顺序来格式化日和月(以紧凑形式),而不是年?所以对于英语它应该是 "Sep 20" 但对于瑞典语“20 sep.”。
为了比较,在 Cocoa 平台上,我可以执行以下操作(在 Swift 中):
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "sv_SE")
formatter.setLocalizedDateFormatFromTemplate("MMM d")
print(formatter.string(from: Date()))
这将正确地扭转局面。 Java SDK 有类似的功能吗?我一直在尝试使用 DateTimeFormatter
和较旧的 SimpleTimeFormat
API 的各种形式,但没有成功。
注意: 与 this question 不同,我不想要包含年份的完整媒体格式。我也不想要 DateTimeFormatter.ofPattern("MMM d")
,因为它在瑞典语中给出了错误的结果,或者 DateTimeFormatter.ofPattern("d MMM")
,因为它在英语中给出了错误的结果。
您可以在 Java 中使用 LocalDate:
LocalDate dt = LocalDate.parse("2019-09-20");
System.out.println(dt);
DateTimeFormatter ft = DateTimeFormatter.ofPattern("dd MMM", new Locale("sv","SE"));
System.out.println(ft.format(dt));
不,对不起。我知道没有 Java 库会自动将 "MMM d"
转换为 20 sep.
,因为语言环境更喜欢月份缩写前的日期。
您可以尝试这样修改 :
DateTimeFormatter ft =
DateTimeFormatter
.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(Locale.forLanguageTag("sv-SE"))
;
然而结果是:
20 sep. 2019
它包括你没有要求的年份。
高级解决方案将使用 DateTimeFormatterBuilder
class to build DateTimeFormatter
个对象。
DateTimeFormatterBuilder
.getLocalizedDateTimePattern(
FormatStyle.MEDIUM,
null,
IsoChronology.INSTANCE,
Locale.forLanguageTag("sv-SE")
)
这个returnsd MMM y
。修改此字符串以删除它之前的 y
和 space。请注意,在其他语言中,y
可能是 yy
、yyyy
或 u
,并且可能不会出现在字符串的最后。将修改后的格式模式字符串传递给 DateTimeFormatter.ofPattern
.
可能摇摇欲坠。即使您查看了所有可用语言环境的格式模式字符串,CLDR(字符串的来源)的下一个版本可能仍然包含惊喜。但我认为这是我们能做的最好的。如果是我,我会考虑抛出一个异常,以防我检测到来自 getLocalizedDateTimePattern
的字符串看起来不像我知道如何修改的字符串。
您可以获得 DateFormat
的模式并删除年份:
val locale: Locale
val datePattern = (DateFormat.getDateInstance(DateFormat.MEDIUM, locale) as SimpleDateFormat).toPattern()
.replace("y", "").trim { it < 'A' || it > 'z' }
有没有办法按照 Java/Kotlin 中正确的语言环境顺序来格式化日和月(以紧凑形式),而不是年?所以对于英语它应该是 "Sep 20" 但对于瑞典语“20 sep.”。
为了比较,在 Cocoa 平台上,我可以执行以下操作(在 Swift 中):
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "sv_SE")
formatter.setLocalizedDateFormatFromTemplate("MMM d")
print(formatter.string(from: Date()))
这将正确地扭转局面。 Java SDK 有类似的功能吗?我一直在尝试使用 DateTimeFormatter
和较旧的 SimpleTimeFormat
API 的各种形式,但没有成功。
注意: 与 this question 不同,我不想要包含年份的完整媒体格式。我也不想要 DateTimeFormatter.ofPattern("MMM d")
,因为它在瑞典语中给出了错误的结果,或者 DateTimeFormatter.ofPattern("d MMM")
,因为它在英语中给出了错误的结果。
您可以在 Java 中使用 LocalDate:
LocalDate dt = LocalDate.parse("2019-09-20");
System.out.println(dt);
DateTimeFormatter ft = DateTimeFormatter.ofPattern("dd MMM", new Locale("sv","SE"));
System.out.println(ft.format(dt));
不,对不起。我知道没有 Java 库会自动将 "MMM d"
转换为 20 sep.
,因为语言环境更喜欢月份缩写前的日期。
您可以尝试这样修改
DateTimeFormatter ft =
DateTimeFormatter
.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(Locale.forLanguageTag("sv-SE"))
;
然而结果是:
20 sep. 2019
它包括你没有要求的年份。
高级解决方案将使用 DateTimeFormatterBuilder
class to build DateTimeFormatter
个对象。
DateTimeFormatterBuilder
.getLocalizedDateTimePattern(
FormatStyle.MEDIUM,
null,
IsoChronology.INSTANCE,
Locale.forLanguageTag("sv-SE")
)
这个returnsd MMM y
。修改此字符串以删除它之前的 y
和 space。请注意,在其他语言中,y
可能是 yy
、yyyy
或 u
,并且可能不会出现在字符串的最后。将修改后的格式模式字符串传递给 DateTimeFormatter.ofPattern
.
可能摇摇欲坠。即使您查看了所有可用语言环境的格式模式字符串,CLDR(字符串的来源)的下一个版本可能仍然包含惊喜。但我认为这是我们能做的最好的。如果是我,我会考虑抛出一个异常,以防我检测到来自 getLocalizedDateTimePattern
的字符串看起来不像我知道如何修改的字符串。
您可以获得 DateFormat
的模式并删除年份:
val locale: Locale
val datePattern = (DateFormat.getDateInstance(DateFormat.MEDIUM, locale) as SimpleDateFormat).toPattern()
.replace("y", "").trim { it < 'A' || it > 'z' }