user66875
user66875

Reputation: 2608

Jackson Parsing of Date fails on some machines

I'm using Jackson to parse a JSON and the deserialization fails because of a date field defined as:

@JsonProperty("jcr:created")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z")
private Date created;

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.util.Date from String "Wed Sep 14 2016 15:37:40 GMT+0200": expected format "EEE MMM dd yyyy HH:mm:ss 'GMT'Z"

The JSON content looks like this:

"jcr:created": "Thu Feb 04 2016 09:32:14 GMT+0100"

What's the issue with the pattern?

Upvotes: 2

Views: 247

Answers (1)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79075

java.time

The java.util date-time API and their corresponding parsing/formatting type, SimpleDateFormat are outdated and error-prone. In March 2014, the modern Date-Time API was released as part of the Java 8 standard library which supplanted the legacy date-time API and since then it is strongly recommended to switch to java.time, the modern date-time API.

Also, never use date-time parsing/formatting API without specifying a Locale.

Solution using java.time

Since your date-time string has timezone information, you should praise it into ZonedDateTime.

@JsonProperty("jcr:created")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "EEE MMM dd yyyy HH:mm:ss VVXX", locale = Locale.ENGLISH)
private ZonedDateTime created;

Demo:

class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss VVXX", Locale.ENGLISH);
        String created = "Thu Feb 04 2016 09:32:14 GMT+0100";
        ZonedDateTime zdt = ZonedDateTime.parse(created, dtf);
        System.out.println(zdt);
    }
}

Output:

2016-02-04T08:32:14Z[GMT]

ONLINE DEMO

Learn more about the modern Date-Time API from Trail: Date Time.

If for any reason, you want to carry on with the error-prone legacy API, simply include locale in the annotation

@JsonProperty("jcr:created")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z", locale = Locale.ENGLISH)
private Date created;

Demo:

class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'Z", Locale.ENGLISH);
        String created = "Thu Feb 04 2016 09:32:14 GMT+0100";
        Date date = sdf.parse(created);
        System.out.println(date);
    }
}

Output:

Thu Feb 04 08:32:14 GMT 2016

ONLINE DEMO

Upvotes: 4

Related Questions