Ernesto
Ernesto

Reputation: 944

OffsetDateTime jsonFormat allowing two type of patterns

I am implementing app in Spring Boot. Using Jackson.

Is there anyway to specify JsonFormat for parsing two types of date like:

My current field:

  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss Z")
  private OffsetDateTime interval;

Do I have to somewhere specify some ObjectMapper in configuration?

I am retrieving this error:

 com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.OffsetDateTime` from String "2020-10-06T10:15:30+01:00": Failed to deserialize java.time.OffsetDateTime: (java.time.format.DateTimeParseException) Text '2020-10-06T10:15:30+01:00' could not be parsed at index 10

Regards

Upvotes: 1

Views: 3303

Answers (1)

Andreas
Andreas

Reputation: 159086

You need to parse using a DateTimeFormatter with optional zone offset, so you need a custom JsonDeserializer:

public class OffsetDateTimeOptionalZoneDeserializer extends StdScalarDeserializer<OffsetDateTime> {
    private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
            .optionalStart()
            .appendOffsetId()
            .optionalEnd()
            .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
            .toFormatter();

    public OffsetDateTimeOptionalZoneDeserializer() { super(OffsetDateTime.class); }

    @Override
    public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        return OffsetDateTime.parse(p.getText(), formatter);
    }
}

Test

public class Test {

    @JsonDeserialize(using = OffsetDateTimeOptionalZoneDeserializer.class)
    private OffsetDateTime interval;

    public static void main(String[] args) throws Exception {
        String json = "[" +
                        "{ \"interval\": \"2020-10-06T10:15:30+01:00\" }," +
                        "{ \"interval\": \"2020-10-06T10:15:30Z\" }," +
                        "{ \"interval\": \"2020-10-06T10:15:30\" }" +
                      "]";
        
        ObjectMapper mapper = new ObjectMapper();
        Test[] tests = mapper.readValue(json, Test[].class);
        for (Test t : tests)
            System.out.println(t.interval);
    }
}

Output

2020-10-06T10:15:30+01:00
2020-10-06T10:15:30Z
2020-10-06T10:15:30Z

Upvotes: 4

Related Questions