I am using Java 8 DateTime and Jackson jsr 310 support in a Spring Boot application.
I disabled SerializationFeature.WRITE_DATES_AS_TIMESTAMPS to force Jackson to serialize the localDatetime to string instead of int array.
But I found a weird format problem when the datetime microsecond or nonaseconds are end of 0. I think the serialized result could be equals the date.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), but it is not, the format method omitted the zeros.
The complete the example test codes.
private LocalDateTime date;
private OffsetDateTime offsetDate;
private ZonedDateTime zonedDate;
@Before
public void setup() throws ServletException {
date = LocalDateTime.of(2015, 8, 15, 11, 40, 10, 100_000_000);
offsetDate = OffsetDateTime.of(2015, 8, 15, 11, 40, 10, 100_000_000, ZoneOffset.ofHours(8));
zonedDate = ZonedDateTime.of(2015, 8, 15, 11, 40, 10, 100_000_000, ZoneId.of("Asia/Shanghai"));
}
@Test
public void testDateFormat() throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("localDate", date);
map.put("offsetDate", offsetDate);
map.put("zonedDate", zonedDate);
String json = objectMapper.writeValueAsString(map);
log.debug("converted json result @" + json);
JsonNode rootNode = objectMapper.readTree(json);
JsonNode localDateNode = rootNode.get("localDate");
assertEquals("local date should be equals", date.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), localDateNode.textValue());
JsonNode offsetDateNode = rootNode.get("offsetDate");
assertEquals("offsetDate date should be equals", offsetDate.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME), offsetDateNode.textValue());
JsonNode zonedDateNode = rootNode.get("zonedDate");
assertEquals("zonedDate date should be equals", zonedDate.format(DateTimeFormatter.ISO_ZONED_DATE_TIME), zonedDateNode.textValue());
}
The test failed, and the log debug prints
{
"zonedDate":"2015-08-15T11:40:10.100+08:00[Asia/Shanghai]",
"localDate":"2015-08-15T11:40:10.100",
"offsetDate":"2015-08-15T11:40:10.1+08:00"
}
zonedDate and localDate microseconds are end with 00, but offsetDate is not. And date.format also get different result which micrseconds is NOT end with 00.
The print result of format, toString, the json text
LocalDateTime format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)@2015-08-15T11:40:10.1
LocalDateTime toString @2015-08-15T11:40:10.100
LocalDateTime serialized json node text @2015-08-15T11:40:10.100
OffsetDateTime format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)@2015-08-15T11:40:10.1+08:00
OffsetDateTime toString @2015-08-15T11:40:10.100+08:00
OffsetDateTime serialized json node text @2015-08-15T11:40:10.1+08:00
ZonedDateTime format(DateTimeFormatter.ISO_ZONED_DATE_TIME)@2015-08-15T11:40:10.1+08:00[Asia/Shanghai]
ZonedDateTime toString @2015-08-15T11:40:10.100+08:00[Asia/Shanghai]
ZonedDateTime serialized json node text @2015-08-15T11:40:10.100+08:00[Asia/Shanghai]
- It seems the toString result should be the desired result in Jackson serialization, in above logging, OffsetDateTime json node microseconds text should be end with 00 .
- Why the format method result omits the ending 00?
The complete sample codes can be found from my github.com.
Your test has 2 problems:
ObjectMapperserialized result andDateTimeFormatterformatted result. Each has their own defaults and configuration options and it's no surprise that the results are different.100_000_000is really1and according to ISO_LOCAL_TIME definition,DateTimeFormatterprints "One to nine digits for the nano-of-second. As many digits will be output as required.". In your case, only 1 digit is required and that's exactly what you got in the output forLocalDateTime.I'm not entirely clear what you're trying to do here and what is the purpose of the tests that you wrote. If you're expecting 3 digits of nanosecond precision from your formatter, you've to roll your own. Depending on
toStringformatting in your code is a bad idea.