2

I have this date string coming in through JSON: "29-OCT-21 12.00.00.000000000 AM UTC". I want to save it as a ZonedDateTime data type.

I have the property set in the model as such:

 @JsonProperty("createdTs") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MMM-yy hh.mm.ss.SSSSSSSSS a z", with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES) private ZonedDateTime createdTs; 

I am getting an error:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.time.ZonedDateTime` from String "29-OCT-21 12.00.00.000000000 AM UTC": Failed to deserialize java.time.ZonedDateTime: (java.time.format.DateTimeParseException) Text '29-OCT-21 12.00.00.000000000 AM UTC' could not be parsed 

I can't figure out what is wrong. The pattern works just fine in the formatter in test cases, like this:

DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("dd-MMM-yy hh.mm.ss.SSSSSSSSS a z").toFormatter( Locale.getDefault()); locationPayload.setcreatedTs(ZonedDateTime.parse("29-OCT-21 12.00.00.000000000 AM UTC", formatter)); 
6
  • Not that it answers your question, but why are you using that format? Why not use something more standard? Commented Dec 11, 2023 at 17:07
  • Also, have you registered the JavaTimeModule? Commented Dec 11, 2023 at 17:19
  • That was the only format that I found that worked. What would be a more standard format? Also, how do I register the JavaTimeModule? Commented Dec 11, 2023 at 17:52
  • 1
    How to register is in the link I gave. The standard format for the date and time would be ISO 8601 (RFC 3339), such as 2021-10-29T00:00:00Z. Z means UTC, so if that's the only time zone you need, then you are set. You also wouldn't need a ZonedDateTime but could instead use an Instant or an OffsetDateTime. Commented Dec 11, 2023 at 19:49
  • If you actually need to support other time zones, then a ZonedDateTime is appropriate, and you would specify the time zone as its IANA identifier, such as America/New_York - either following the string (separated by space or in square brackets without a space), or as a separate field. Commented Dec 11, 2023 at 19:51

1 Answer 1

1
+100

This issue is related to the inability of the JsonFormat to handle the complex date-time format you have in the JSON string. To resolve this, you can create a custom deserializer for the ZonedDateTime type.

Here's an example:

import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; public class ZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> { private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder() .parseCaseInsensitive() .appendPattern("dd-MMM-yy hh.mm.ss.SSSSSSSSS a z") .toFormatter(); @Override public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { String dateString = jsonParser.getText(); return ZonedDateTime.parse(dateString, FORMATTER); } } 

Your property

public class Test { @JsonProperty("createdTs") @JsonDeserialize(using = ZonedDateTimeDeserializer.class) private ZonedDateTime createdTs; //Getter & Settere } 

Test

 public static void main(String[] args) throws JsonProcessingException { String s = """ { "createdTs": "29-OCT-21 12.00.00.000000000 AM UTC" } """; Test t = JsonMapper.builder().findAndAddModules().build().readValue(s, Test.class); System.out.println(t); } 

Output Test(createdTs=2021-10-29T00:00Z[UTC])

Try it and let me know

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.