我一直试图将某些日期转换为特定于语言环境的格式。 可以说我的日期是:2019年1月17日
我想将此日期转换为以下语言环境:
localized time for en-GB: 17 January 2019
localized time for es-ES: 17 de enero de 2019
localized time for zh-CN: 2019年1月17日
localized time for de-DE: 17. Januar 2019
localized time for fr-FR: 17 janvier 2019
localized time for it-IT: 17 gennaio 2019
localized time for ja-JP: 2019年1月17日
localized time for ko-KR: 2019년 1월 17일
我尝试了多种方法来实现这一目标:
方法1:
final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM,
Locale.forLanguageTag(locale)));
针对不同语言环境的输出:
localized time for en-GB: 17 January 2019
localized time for es-ES: 17 de enero de 2019
localized time for zh-CN: 2019年1月17日
localized time for de-DE: 17. Januar 2019
localized time for fr-FR: 17 janvier 2019
localized time for it-IT: 17 gennaio 2019
localized time for ja-JP: 2019/01/17 [Getting the date in numerical form]
localized time for ko-KR: 2019년 1월 17일 (목) [Getting this extra character at the end for ko-KR]
方法2:
ZonedDateTime zoned = ZonedDateTime.now();
DateTimeFormatter pattern = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(Locale.forLanguageTag(locale));
针对不同语言环境的输出:
zoned fek long ja-JP: 2019年1月17日
zoned fek long ko-KR: 2019년 1월 17일 목요일
zoned fek long es-ES: jueves 17 de enero de 2019
zoned fek long fr-FR: jeudi 17 janvier 2019
zoned fek long it-IT: giovedì 17 gennaio 2019
zoned fek long de-DE: Donnerstag, 17. Januar 2019
zoned fek long ko-KR: jeudi 17 janvier 2019
在这种方法中,JP看起来不错,但所有其他语言环境在输出中也有Day。
我必须显示上面提到的日期。
答案 0 :(得分:3)
使用命令行选项-Djava.locale.providers=CLDR,COMPAT
运行方法2。例如:
java -Djava.locale.providers=CLDR,COMPAT YourApp
输出:
zoned fek long en-GB: 17 January 2019 zoned fek long es-ES: 17 de enero de 2019 zoned fek long zh-CN: 2019年1月17日 zoned fek long de-DE: 17. Januar 2019 zoned fek long fr-FR: 17 janvier 2019 zoned fek long it-IT: 17 gennaio 2019 zoned fek long ja-JP: 2019年1月17日 zoned fek long ko-KR: 2019년 1월 17일
我发现在Java 9上无法重现您的问题。有了FormatStyle.LONG
,我得到了2019年1月17日
的日语报告,其中您报告了2019/01/17
。 Java从不同来源获取日期格式作为其区域数据的一部分。在Java中,Unicode Common Locale Data Repository (CLDR)的8种语言环境数据是Java附带的,但是Java自己的语言环境数据被用作默认语言。与Java 9相反,CLDR数据用作默认值。因此,使用上述命令行选项的目的是告诉Java 8在使用Java之前先使用CLDR。 Java自己的语言环境数据指定为COMPAT。
另一个选择当然是升级到Java 9、10或11。这也将为您提供所需的结果。
无法在命令行中添加任何其他选项,因为这 应用程序将通过其他系统运行。
很不幸。您可能要再问一次。另一方面,命令行选项可能会改变该其他系统所有部分的行为,因此您可能无法完全避免这种情况。
如果其他所有方法均失败,请为FormatStyle.LONG
无法满足您要求的语言环境编写一些例外情况。 The answer by Joop Eggen显示了执行此操作的一种方法。
一旦另一个系统的管理者决定升级到Java 9或更高版本,除非他们使用命令行选项在COMAPT
之前使用CLDR
,否则语言环境数据将发生变化,然后您将拥有有机会简化您的代码。
答案 1 :(得分:3)
由于您不想以自定义格式列出所有语言环境,因此修补例外似乎更好。可以是自定义模式,也可以只是选择其他样式/后期编辑。
String[] locales = {"en-GB", "es-ES", "zh-CN", "de-DE", "fr-FR", "it-IT",
"ja-JP", "ko-KR", "ko-KP"};
for (String loc : locales) {
String[] langCtry = loc.split("-");
Locale locale = new Locale(langCtry[0], langCtry[1]);
Locale.setDefault(locale);
LocalDate.set(2019, 1, 17);
FormatStyle style = locale.getLanguage().equals("ja") ? FormatStyle.FULL
: FormatStyle.LONG;
DateTimeFormatter.ofLocalizedDate(style);
String text = format.format(date);
if (locale.getLanguage().equals("ko")) {
text = text.replaceFirst("\\s\\S+$", "");
}
System.out.printf("%s: %s%n", locale, text);
}
此补丁以不同的方式修补 ja 和 ko 。
用于检查预期结果的单元测试套件可能会有用,因为特定于区域的数据可能会随时间变化。