Java 10 日期时间格式化程序模式符号,用于添加句点"E"和"MMM"



所以在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 映像在美国区域设置上运行,我的机器在澳大利亚区域上运行:)

验证Locale

标点符号和相关事项(缩写、拼写、元素顺序(被定义为文化规范的一部分。在爪哇,这些文化规范由Locale指定。

运行时区域设置不同

一个可能的问题是,您在运行代码时没有显式指定Locale,这意味着您隐式依赖于 JVM 的当前缺省语言环境。该默认值可能因运行时环境而异。

记录默认区域设置以进行验证。

Locale.getDefault().toString()

研究下面的代码示例,了解如何显式指定Locale。我建议始终明确Locale(顺便说一下,时区也是如此(。

定义在运行时有所不同

请注意,Java 9 的日期时间本地化发生了重大变化:JEP 252:默认使用 CLDR 语言环境数据。至少对于基于 OpenJDK 的 JVM,有关这些文化规范的信息源切换到 Unicode 联盟提供的通用语言环境数据存储库

对于此处讨论的特定情况,使用Locale.US时,我们认为没有区别,如下面的代码示例所示。但是对于某些语言环境,您可能确实会看到 Java 8 及更早版本与 Java 9 及更高版本之间的差异。

所以,再一次,我想知道您的问题的第二个示例中是否涉及不同的区域设置。解决方法是显式指定您或您的用户期望的区域设置,而不是隐式依赖 JVM 的当前瞬时默认值(默认值可以在运行时随时更改!

无法确认问题

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 中通过 Azul Systems 在 IntelliJ 2018.3 中的基于 OpenJDK 的祖鲁 JVM 在 macOS High Sierra 下的 MacBook Pro Retina 上运行时,我得到:

10.0.2

en_US

周四 30 8月 2018

对于 Java 8,请参阅在 IdeOne.com 实时运行的相同代码。请注意,IdeOne.com 中使用的 JVM 仅固定为单个语言环境,Locale.US.

en_US

1.8.0_112

输出: 周四 30 8月 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 );

2018年8月30日(周四

(

最新更新