Jackson Deserialization Issue for Zoneddatetime

Java Spring: Jackson deserialization to ZonedDateTime

The Z in the pattern won't accept a literal 'Z' in the value, using X instead should work:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX")

The pattern is specified as a Java SimpleDateFormat - Java 10 reference here.

Deserialize JSON date format to ZonedDateTime using objectMapper

I have control only over the ObjectMapper. Is there any possible configuration that can make this work?

As long as you are happy with default values for the time and for the timezone, you could work around it with a custom deserializer:

public class ZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {

@Override
public ZonedDateTime deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext)
throws IOException {

LocalDate localDate = LocalDate.parse(
jsonParser.getText(),
DateTimeFormatter.ISO_LOCAL_DATE);

return localDate.atStartOfDay(ZoneOffset.UTC);
}
}

Then add it to a module and register the module to your ObjectMapper instance:

SimpleModule module = new SimpleModule();
module.addDeserializer(ZonedDateTime.class, new ZonedDateTimeDeserializer());

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);

If adding the deserializer to a module doesn't suit you (in the sense this configuration will be applied to other ZonedDateTime instances), then you could rely on mix-ins to define which fields the deserializer will be applied to. First define a mix-in interface, as shown below:

public interface MarkdownMixIn {

@JsonDeserialize(using = ZonedDateTimeDeserializer.class)
ZonedDateTime getDate();
}

And then bind the mix-in interface to the desired class:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Markdown.class, MarkdownMixIn.class);

Deserialize Java 8 LocalDateTime with Jackson

Wrong data type

As others commented, you are using the wrong data types.

The LocalDateTime class purposely lacks any concept of time zone or offset-from-UTC. So this class cannot represent a moment, a specific point on the timeline. This class represents only a date and time-of-day, but we have no idea whether that date and time-of-day is intended for Tokyo Japan, Toulouse France, or Toledo Ohio US.

So the LocalDateTime class does not fit your inputs.

The string inputs:

  • 2022-04-05T05:00:00.000+00:00
  • 2022-04-05T05:00:00.000Z

… both represent a moment as seen in UTC, with an offset from UTC of zero hours-minutes-seconds. The Z on the end of the second one is a standard ISO 8601 abbreviation of +00:00, and is pronounced “Zulu”.

Instant & OffsetDateTime

You can parse both such inputs as Instant objects or as more flexible OffsetDateTime objects.

These input strings use standard ISO 8601 formats. The java.time classes use these formats by default when parsing/generating. So no need to specify a formatting pattern.

Instant instant = Instant.parse( "2022-04-05T05:00:00.000+00:00" ) ;
Instant instant2 = Instant.parse( "2022-04-05T05:00:00.000Z" ) ;

OffsetDateTime odt = OffsetDateTime.parse( "2022-04-05T05:00:00.000+00:00" ) ;
OffsetDateTime odt2 = OffsetDateTime.parse( "2022-04-05T05:00:00.000Z" ) ;

See this code run live at IdeOne.com.

instant: 2022-04-05T05:00:00Z
instant2: 2022-04-05T05:00:00Z
odt: 2022-04-05T05:00Z
odt2: 2022-04-05T05:00Z

One Comment mentioned using ZonedDateTime. That would be ill-advised. Time zones have names in format of Continent/Region such as Europe/Paris or Pacific/Auckland. Your inputs have only offsets, not time zones. So ZonedDateTime would be misleading and confusing here.

An offset is merely a number of hours-minutes-seconds ahead or behind the prime meridian of UTC. A time zone is much more. A time zone is a named history of the past, present, and future changes to the offset used by the people of a particular region.

Jackson deserialize date from Twitter to `ZonedDateTime`

Try to add this annotation over your property

@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="EEE MMM dd HH:mm:ss Z yyyy")
@JsonProperty("created_at")
ZonedDateTime created_at;


Related Topics



Leave a reply



Submit