问题
The following UnitTest is failing when being executed through IntelliJ IDE in a Windows machine (Java 11.0.9) but passes when executed in a Mac or Linux machine with the same version of Java.
@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);
}
For windows the result is the following exception:
java.time.format.DateTimeParseException: Text 'Mon, 14 Dec 2020 20:34:37 GMT' could not be parsed at index 0
回答1:
Never use DateTimeFormatter
without a Locale
.
Since the given date-time is in English, you should use the DateTimeFormatter
with 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);
}
}
Output:
2020-12-14T20:34:37Z[GMT]
By default, DateTimeFormatter#ofPattern uses the default FORMAT locale which the JVM sets during startup based on the host environment. I have tried to illustrate the problem through the following demo:
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, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(responseTimeStamp, 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, 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));
}
}
Output:
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)
来源:https://stackoverflow.com/questions/65363205/zoneddatetime-parse-fails-for-exact-the-same-string-in-windows-but-works-in-ma