TheBrizzler
TheBrizzler

Reputation: 33

Serialize LocalDateTime with only milliseconds with Jackson

I want to serialize a LocalDateTime to textual format while only showing milliseconds. I tried the following example:

final ObjectMapper mapper = new ObjectMapper();

mapper.registerModule(new Jdk8Module());
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);

final LocalDateTime t = LocalDateTime.of(2014, 3, 30, 12, 30, 23, 123456789);

System.out.println(mapper.writeValueAsString(t));

This outputs:

"2014-03-30T12:30:23.123456789"

So the precision is still in nanoseconds, despite to not show them as per mapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS).

I expected:

"2014-03-30T12:30:23.123"

Why is this? How can I fix this?

Upvotes: 3

Views: 4972

Answers (1)

amseager
amseager

Reputation: 6391

Since you disabled WRITE_DATES_AS_TIMESTAMPS, enabling or disabling WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS does nothing because localDateTime isn't in the timestamp representation anymore.

If you enable WRITE_DATES_AS_TIMESTAMPS and then disable WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, you'll get the desired result but in another form ([2014,3,30,12,30,23,123]), so it's also not an option.

So there are basically only two options to achieve the expected result:

  1. The easiest - use this: System.out.println(mapper.writeValueAsString(t.truncatedTo(ChronoUnit.MILLIS)));

    (Remember that you can safely remove mapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);, as it does nothing in this case).

  2. A more complicated way (without truncating the time):

    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(new LocalDateTimeSerializer(dateTimeFormatter));
    
    final ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(simpleModule);
    
    final LocalDateTime t = LocalDateTime.of(2014, 3, 30, 12, 30, 23, 123456789);
    
    System.out.println(mapper.writeValueAsString(t));
    

    (In that case you don't even need to use JavaTimeModule).

Upvotes: 4

Related Questions