SimpleDateFormat .format()在Java8和Java11中给出不同的结果

时间:2019-07-16 03:22:58

标签: java java-8 simpledateformat java-11

我有这小段代码:

import java.text.SimpleDateFormat;
import java.util.Date;

public class Main {

    public static void main(String[] args) {

        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");

        System.out.println(format.format(new Date()));

    }
}

对于Java 8,输出为:

Tue, 16 Jul 2019 13:16:54 AEST

使用Java 11:

Tue., 16 Jul. 2019 13:16:54 AEST

为什么会有区别,如何修改我的代码以使其在两个Java版本中均能正常工作?

在发现此问题时,我实际上是在使用Handlebars,可以将其范围缩小到Java版本-但是知道如何使用Handlebars为相同格式的字符串产生相同的结果会很酷。 ..)

1 个答案:

答案 0 :(得分:8)

TL; DR

使用如下定义的系统属性java.locale.providers运行Java 9和更高版本(包括Java 11):

java -Djava.locale.providers=COMPAT,CLDR YourApp

现在输出的结果中没有点,其格式与Java 8相同,例如:

  

2019年7月16日,星期二14:24:15 AEST

CLDR

Java会从多达四个来源获取其语言环境数据,包括一周中的几天和不同语言中数月的缩写。最多Java 8 Java自己的语言环境数据是默认设置。在Java 8中,还包括Unicode Common Locale Data Repository(CLDR;请参阅底部的链接)中的数据,而从Java 9中,它们是默认值。通过在上述系统属性中指定COMPAT,仍然可以包含和访问Java自己的数据。我们需要将其放在字符串的开头,因为依次尝试了源代码。

一个人可能已经期望另一个(甚至更好的)解决方案是在所有Java版本中使用CLDR。奇怪的是,在这种情况下,这并不能为我们提供所有Java版本相同的格式。这是将属性设置为CLDR,JRE时的输出(JRE是COMPAT的旧名称,在Java 8上,我们需要改用它)。

在Java 8上:

  

2019年7月16日,星期二14:35:02 AEST

在Java 9和11上:

  

星期二,2019年7月16日14:35:52 AEST

CLDR具有版本,不同的Java版本不包含相同的版本。

java.time

这是我用于上述输出的摘录。

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
            "EEE, dd MMM yyyy HH:mm:ss zzz", Locale.forLanguageTag("en-AU"));
    ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Australia/Sydney"));
    System.out.println(now.format(formatter));

我正在使用并推荐使用Java.time(现代Java日期和时间API)。您使用的日期时间类SimpleDateFormatDate早已过时并且设计得很差,所以我建议避免使用它们。在Java 8及更高版本上,当然没有理由要使用它们,并且java.time也已反向移植到Java 6和7。

链接