问题描述
以下 UnitTest 在 Windows 机器(Java 11.0.9)中通过 IntelliJ IDE 执行时失败,但在具有相同 Java 版本的 Mac 或 Linux 机器上执行时通过。
@Test
public void rfc1123JaveTimeUtilParsing(){
final String rfc1123Pattern = "EEE,dd MMM yyyy HH:mm:ss z";
final String responseTimeStamp = "Mon,14 Dec 2020 20:34:37 GMT";
DateTimeFormatter javaTimeDateTimeFormatter = DateTimeFormatter.ofPattern(rfc1123Pattern);
zoneddatetime javaFinalTime = zoneddatetime.parse(responseTimeStamp,javaTimeDateTimeFormatter);
Assert.assertNotNull(javaFinalTime);
}
对于 Windows,结果是以下异常:
java.time.format.DateTimeParseException:无法在索引 0 处解析文本“Mon,14 Dec 2020 20:34:37 GMT”
解决方法
切勿在没有 DateTimeFormatter
的情况下使用 Locale
。
由于给定的日期时间是英文的,您应该将 DateTimeFormatter
与 Locale.ENGLISH
一起使用。
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
final String responseTimeStamp = "Mon,14 Dec 2020 20:34:37 GMT";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE,dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(responseTimeStamp,dtf);
System.out.println(zdt);
}
}
输出:
2020-12-14T20:34:37Z[GMT]
默认情况下,DateTimeFormatter#ofPattern
使用 JVM 在启动时根据宿主环境设置的 default FORMAT locale。我试图通过以下演示来说明问题:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
final String responseTimeStamp = "Mon,14 Dec 2020 20:34:37 GMT";
DateTimeFormatter dtfWithDefaultLocale = null;
System.out.println("JVM's Locale: " + Locale.getDefault());
// DateTimeFormatter with the default Locale
dtfWithDefaultLocale = DateTimeFormatter.ofPattern("EEE,dd MMM yyyy HH:mm:ss z");
System.out.println("DateTimeFormatter's Locale: " + dtfWithDefaultLocale.getLocale());
System.out.println(
"Parsed with JVM's default locale: " + ZonedDateTime.parse(responseTimeStamp,dtfWithDefaultLocale));
// DateTimeFormatter with Locale.ENGLISH explicitly (recommended)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE,dtf);
System.out.println("Parsed with Locale.ENGLISH: " + zdt);
// Setting the JVM's default locale to Locale.FRANCE
Locale.setDefault(Locale.FRANCE);
System.out.println("JVM's Locale: " + Locale.getDefault());
// DateTimeFormatter with the default Locale
dtfWithDefaultLocale = DateTimeFormatter.ofPattern("EEE,dtfWithDefaultLocale));
}
}
输出:
JVM's Locale: en_GB
DateTimeFormatter's Locale: en_GB
Parsed with JVM's default locale: 2020-12-14T20:34:37Z[GMT]
Parsed with Locale.ENGLISH: 2020-12-14T20:34:37Z[GMT]
JVM's Locale: fr_FR
DateTimeFormatter's Locale: fr_FR
Exception in thread "main" java.time.format.DateTimeParseException: Text 'Mon,14 Dec 2020 20:34:37 GMT' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:598)
at Main.main(Main.java:29)