我有这小段代码:
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为相同格式的字符串产生相同的结果会很酷。 ..)
答案 0 :(得分:8)
使用如下定义的系统属性java.locale.providers
运行Java 9和更高版本(包括Java 11):
java -Djava.locale.providers=COMPAT,CLDR YourApp
现在输出的结果中没有点,其格式与Java 8相同,例如:
2019年7月16日,星期二14:24:15 AEST
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版本不包含相同的版本。
这是我用于上述输出的摘录。
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)。您使用的日期时间类SimpleDateFormat
和Date
早已过时并且设计得很差,所以我建议避免使用它们。在Java 8及更高版本上,当然没有理由要使用它们,并且java.time也已反向移植到Java 6和7。