Spring Boot アプリケーションで Java 8 DateTime と Jackson jsr 310 のサポートを使用しています。
SerializationFeature.WRITE_DATES_AS_TIMESTAMPSを無効 にして、Jackson に localDatetime を int 配列ではなく文字列にシリアル化するよう強制しました。
しかし、datetime マイクロ秒または nonaseconds が 0 の終わりであるときに、奇妙なフォーマットの問題が見つかりました。シリアル化された結果はdate.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)と等しい可能性があると思いますが、そうではなく、フォーマットメソッドがゼロを省略しました。
サンプル テスト コードを完成させます。
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());
}
テストが失敗し、ログ デバッグが出力されます
{
"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とlocalDate のマイクロ秒は00で終わりますが、offsetDate はそうではありません。また、date.formatは、マイクロ秒が00で終わらない別の結果も取得します。
format の出力結果、toString、json テキスト
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]
- toStringの結果はJackson シリアライゼーションで望ましい結果になるはずです。上記のロギングでは、OffsetDateTime json node microseconds text は00で終わる必要があります。
- format メソッドの結果で末尾の00が省略されるのはなぜですか?
完全なサンプル コードは、私の github.com から見つけることができます。