You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DateTimeFormatter使用parseDefaulting抛出异常的原因排查

DateTimeFormatter解析毫秒时的冲突异常分析

问题场景

定义了如下DateTimeFormatter:

private static final DateTimeFormatter DATE_PATTERN = new DateTimeFormatterBuilder()
    .appendPattern("yyyy-MM-dd[ ]['T'][HH:mm:ss][.SSSSSS][.SSSSS][.SSSS][.SSS][.SS][.S][X]")
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
    .parseDefaulting(ChronoField.MILLI_OF_SECOND, 0)
    .toFormatter()
    .withZone(ZoneOffset.UTC); // assume incoming is UTC

该格式化器被用于以下方法:

public static Function<String, String> getFormattedDate() {
  return dateTime -> {
    try {
      ZonedDateTime timeRemoved =
          ZonedDateTime.parse(dateTime, DATE_PATTERN).truncatedTo(ChronoUnit.DAYS);
      return DateTimeFormatter.ofPattern(DISPLAY_DATE_PATTERN).format(timeRemoved);
    } catch (Exception e) {
      return null;
    }
  };
}

运行测试用例时抛出异常:

public void test_data_patter_with_ms(){
  String formattedDate = DateTimeUtil.getFormattedDate().apply("2021-04-24T06:57:06.850");
  assertThat(formattedDate, is("2021-04-24T00:00:00Z"));
}

异常信息:

java.time.format.DateTimeParseException: Text '2021-04-24T06:57:06.850' could not be parsed: Conflict found: NanoOfSecond 850000000 differs from NanoOfSecond 0 while resolving MilliOfSecond

注释掉.parseDefaulting(ChronoField.MILLI_OF_SECOND, 0)后测试恢复正常,原因如下:

核心原因

问题出在parseDefaulting的工作逻辑与时间字段的强关联性上:

  1. 解析字符串2021-04-24T06:57:06.850时,.SSS部分会读取到毫秒值850,对应纳秒值为850000000。
  2. 但你通过parseDefaulting(ChronoField.MILLI_OF_SECOND, 0)预先给毫秒字段设置了默认值0,对应纳秒值为0。
  3. Java时间库在解析时会校验关联字段的一致性:毫秒和纳秒是绑定的字段,解析得到的毫秒对应纳秒,与预设默认值的纳秒产生冲突,因此抛出解析异常。

当注释掉这条默认设置后,解析器只会使用从字符串中读取到的毫秒值,没有预设值与之冲突,因此可以正常完成解析。

另外补充:你的代码最终会调用truncatedTo(ChronoUnit.DAYS)截断到日期维度,即使保留毫秒值也不影响最终输出,但解析阶段的字段冲突会直接导致解析失败,因此必须移除这个多余的默认配置。

内容的提问来源于stack exchange,提问作者Dan OConnell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:18:19