Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

java - ZonedDateTime.parse() fails for exact the same string in Windows but works in Mac and Linux

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...