Java 10 个 DateTimeFormatter 模式符号用于 "E" 和 "MMM" 添加句点
Java 10 DateTimeFormatter pattern symbols for "E" and "MMM" adding periods
所以在 Java 8 以下:
DateTimeFormatter df = DateTimeFormatter.ofPattern("E d MMM yyyy");
以这种方式应用时:
LocalDate date = LocalDate.now();
date.format(df);
会产生这样的结果:
"Available on Thu 30 Aug 2018"
然而,当 Java 10 中的 运行 时,完全相同的代码会产生以下内容:
"Available on Thu. 30 Aug. 2018"
注意日和月部分之后的句点...
我很清楚我可以只替换字符串中的句点,但我真的不想这样做。我想知道为什么会发生这种变化,是否有替代模式?
我在网上找不到任何关于此更改的参考资料。
编辑:
根据下面 Basil 的回答,这不是 Java 版本问题。这是一个区域设置问题。带有我的代码的 docker 图像在美国语言环境中是 运行ning,而我的机器在澳大利亚语言环境中是 :)
验证Locale
标点符号和相关事项(缩写、拼写、元素顺序)被定义为文化规范的一部分。在 Java 中,这些文化规范由 Locale
.
指定
语言环境在 运行 时间
发生变化
一个可能的问题是您在未明确指定 Locale
的情况下 运行ning 代码,这意味着您隐含地依赖于 JVM 当前的默认语言环境。该默认值可能因 运行 时间环境而异。
记录您的默认语言环境,以进行验证。
Locale.getDefault().toString()
研究下面的代码示例,了解如何明确指定您的 Locale
。我建议 always 让你的 Locale
明确(顺便说一下,时区也是如此)。
运行时间
定义有所不同
请注意,Java9 的日期时间本地化发生了重大变化:JEP 252: Use CLDR Locale Data by Default. At least for OpenJDK-based JVMs, the source of information about these cultural norms switched to the Common Locale Data Repository provided by the Unicode Consortium。
对于这里讨论的特殊情况,当使用 Locale.US
时,我们看不出有什么区别,您可以在下面的代码示例中看到。但是对于某些语言环境,您可能确实会看到 Java 8 及更早版本与 Java 9 及更高版本之间的差异。
所以,我再次想知道您的问题的第二个示例是否涉及不同的语言环境。修复方法是明确指定您或您的用户期望的语言环境,而不是隐式依赖 JVM 当前的瞬时默认值(默认值可以随时更改 during运行time !).
无法确认问题
System.out.println( System.getProperty( "java.version" ) );
System.out.println( Locale.getDefault().toString() );
LocalDate ld = LocalDate.of( 2018 , Month.AUGUST , 30 );
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E d MMM yyyy" , locale );
String output = ld.format( f );
System.out.println( output );
当 运行 在 Java 10.0.2 中通过 IntelliJ 2018.3 中基于 OpenJDK 的 Zulu JVM by Azul Systems 在 macOS High Sierra 下的 MacBook Pro Retina 上,我得到:
10.0.2
en_US
Thu 30 Aug 2018
对于Java 8,请参见code run live at IdeOne.com。请注意,IdeOne.com 中使用的 JVM 仅固定为单个区域设置,Locale.US
。
en_US
1.8.0_112
output: Thu 30 Aug 2018
澳大利亚
这是一个示例,说明您的输出在其他一些英语地区(例如澳大利亚)如何成为常态。
LocalDate ld = LocalDate.of( 2018 , Month.AUGUST , 30 );
Locale locale = new Locale( "en" , "AU" ); // "en-AU" is English Australia.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E d MMM yyyy" , locale );
String output = ld.format( f );
Thu. 30 Aug. 2018
所以在 Java 8 以下:
DateTimeFormatter df = DateTimeFormatter.ofPattern("E d MMM yyyy");
以这种方式应用时:
LocalDate date = LocalDate.now();
date.format(df);
会产生这样的结果:
"Available on Thu 30 Aug 2018"
然而,当 Java 10 中的 运行 时,完全相同的代码会产生以下内容:
"Available on Thu. 30 Aug. 2018"
注意日和月部分之后的句点...
我很清楚我可以只替换字符串中的句点,但我真的不想这样做。我想知道为什么会发生这种变化,是否有替代模式?
我在网上找不到任何关于此更改的参考资料。
编辑:
根据下面 Basil 的回答,这不是 Java 版本问题。这是一个区域设置问题。带有我的代码的 docker 图像在美国语言环境中是 运行ning,而我的机器在澳大利亚语言环境中是 :)
验证Locale
标点符号和相关事项(缩写、拼写、元素顺序)被定义为文化规范的一部分。在 Java 中,这些文化规范由 Locale
.
语言环境在 运行 时间
发生变化一个可能的问题是您在未明确指定 Locale
的情况下 运行ning 代码,这意味着您隐含地依赖于 JVM 当前的默认语言环境。该默认值可能因 运行 时间环境而异。
记录您的默认语言环境,以进行验证。
Locale.getDefault().toString()
研究下面的代码示例,了解如何明确指定您的 Locale
。我建议 always 让你的 Locale
明确(顺便说一下,时区也是如此)。
运行时间
定义有所不同请注意,Java9 的日期时间本地化发生了重大变化:JEP 252: Use CLDR Locale Data by Default. At least for OpenJDK-based JVMs, the source of information about these cultural norms switched to the Common Locale Data Repository provided by the Unicode Consortium。
对于这里讨论的特殊情况,当使用 Locale.US
时,我们看不出有什么区别,您可以在下面的代码示例中看到。但是对于某些语言环境,您可能确实会看到 Java 8 及更早版本与 Java 9 及更高版本之间的差异。
所以,我再次想知道您的问题的第二个示例是否涉及不同的语言环境。修复方法是明确指定您或您的用户期望的语言环境,而不是隐式依赖 JVM 当前的瞬时默认值(默认值可以随时更改 during运行time !).
无法确认问题
System.out.println( System.getProperty( "java.version" ) );
System.out.println( Locale.getDefault().toString() );
LocalDate ld = LocalDate.of( 2018 , Month.AUGUST , 30 );
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E d MMM yyyy" , locale );
String output = ld.format( f );
System.out.println( output );
当 运行 在 Java 10.0.2 中通过 IntelliJ 2018.3 中基于 OpenJDK 的 Zulu JVM by Azul Systems 在 macOS High Sierra 下的 MacBook Pro Retina 上,我得到:
10.0.2
en_US
Thu 30 Aug 2018
对于Java 8,请参见code run live at IdeOne.com。请注意,IdeOne.com 中使用的 JVM 仅固定为单个区域设置,Locale.US
。
en_US
1.8.0_112
output: Thu 30 Aug 2018
澳大利亚
这是一个示例,说明您的输出在其他一些英语地区(例如澳大利亚)如何成为常态。
LocalDate ld = LocalDate.of( 2018 , Month.AUGUST , 30 );
Locale locale = new Locale( "en" , "AU" ); // "en-AU" is English Australia.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E d MMM yyyy" , locale );
String output = ld.format( f );
Thu. 30 Aug. 2018