How to serialize LocalDateTime with Jackson?
Asked Answered
F

3

24

I got the following piece of code:

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    String now = new ObjectMapper().writeValueAsString(new SomeClass(LocalDateTime.now()));
    System.out.println(now);

And I get this:

{"time":{"hour":20,"minute":49,"second":42,"nano":99000000,"dayOfYear":19,"dayOfWeek":"THURSDAY","month":"JANUARY","dayOfMonth":19,"year":2017,"monthValue":1,"chronology":{"id":"ISO","calendarType":"iso8601"}}}

What I want to achieve is a string in ISO8601

2017-01-19T18:36:51Z

Farseeing answered 19/1, 2017 at 18:53 Comment(2)
Would something like this work: DateFormat df = new SimpleDateFormat("MM/dd/yy hh:mm a"); and then: mapper.setDateFormat(df);Mikiso
My situation is the reverse way, What | want to get is your output and what I am getting is what you are looking for. I have the exact same configuration as you. Any help?Fascia
D
55

This is probably due to mistake in your code. You were using new unconfigured instance of mapper, here is the fix:

 ObjectMapper mapper = new ObjectMapper();
 mapper.registerModule(new JavaTimeModule());
 mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
 String now = mapper.writeValueAsString(new SomeClass(LocalDateTime.now()));
 System.out.println(now);
Dillingham answered 19/1, 2017 at 19:26 Comment(0)
L
9

I use SimpleModule and the best practice for me is to have my own registered implementation for serialization and deserialization:

final SimpleModule localDateTimeSerialization = new SimpleModule();
    localDateTimeSerialization.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
    localDateTimeSerialization.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());

objectMapper.registerModule(localDateTimeSerialization);

Serializer:

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {

  private final DateTimeFormatter format = DateTimeFormatter.ISO_DATE_TIME;

  @Override
  public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    gen.writeString(value.format(format));
  }
  
}

And deserialization:

public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {

  private final DateTimeFormatter fmt = DateTimeFormatter.ISO_DATE_TIME;

  @Override
  public LocalDateTime deserialize(JsonParser p, DeserializationContext context) throws IOException {
    return LocalDateTime.parse(p.getValueAsString(), fmt);
  }
  
}
Loadstone answered 6/6, 2021 at 15:12 Comment(2)
This answer is great as JavaTimeModule will not do the job in any case. For example, when you need the serialisation of a datetime pattern using multiple possible fraction digit formats [.SSS][.SS][.S]. JavaTimeModule would out of the box create .123.12.1. Having a custom implementation is a) great for visibility and b) pretty much straightforward. thx @LoadstoneThin
thanks, this SimpleModule() is so simple to understand and add new customized object-to-json json-to-object formatters. Some formatters may need an application level custom logic.Edp
T
5

This is what you can do for OffsetDateTime:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "uuuu-MM-dd'T'HH:mm:ss.SSSXXXX")
private OffsetDateTime timeOfBirth;

For LocalDateTime you cannot use XXXX (zone offset) because there is no offset information. So you can drop it. But ISO8601 discourages using Local Time as it's ambiguous:

If no UTC relation information is given with a time representation, the time is assumed to be in local time. While it may be safe to assume local time when communicating in the same time zone, it is ambiguous when used in communicating across different time zones. Even within a single geographic time zone, some local times will be ambiguous if the region observes daylight saving time. It is usually preferable to indicate a time zone (zone designator) using the standard's notation.

Tridentum answered 19/1, 2017 at 20:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.