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

DateTimeFormatter解析无分隔符毫秒时间失败的原因及修复方案

为什么DateTimeFormatter解析无分隔符的yyyyMMddHHmmssSSS会失败?怎么修复?

这个问题其实是因为DateTimeFormatter和SimpleDateFormat对模式中连续数字字段的解析逻辑完全不同,我来给你拆解清楚:

问题根源

在SimpleDateFormat里,模式yyyyMMddHHmmssSSS是按固定长度截取来解析的:它会依次取前4位当年份,接下来2位月份,……,第13-14位当秒,最后3位当毫秒——完全不管字段之间有没有分隔符,只要长度对就没问题。

但DateTimeFormatter是基于时间字段语义来解析的:

  • ss代表的是SECOND_OF_MINUTE字段(合法范围0-59)
  • SSS代表的是MILLI_OF_SECOND字段(合法范围0-999)

当这两个字段在模式里连写(没有分隔符)时,解析器会把ssSSS当成一个连续的数字串,尝试将其解析为秒字段的数值(包括小数部分)。比如如果你的时间字符串里秒部分是30,毫秒是123,那解析器会把30123当成秒的值,这显然远远超过了秒的合法范围,直接抛出DateTimeParseException。

修复方法

要让DateTimeFormatter正确解析这种无分隔符的格式,你需要明确告诉它每个字段的长度,避免它把秒和毫秒的数字混在一起。最可靠的方式是用DateTimeFormatterBuilder来构建格式化器:

// 构建自定义格式化器,明确指定秒和毫秒的固定长度
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .appendPattern("yyyyMMddHHmm") // 先处理到分钟部分
    .appendValue(ChronoField.SECOND_OF_MINUTE, 2) // 秒:固定2位
    .appendValue(ChronoField.MILLI_OF_SECOND, 3) // 毫秒:固定3位
    .toFormatter();

// 测试代码
LocalDateTime now = LocalDateTime.now();
String s = formatter.format(now);
System.out.println(now);
System.out.println(s);
System.out.println(LocalDateTime.parse(s, formatter)); // 现在可以正常解析了

这种方式强制解析器按固定长度截取秒和毫秒的部分,完全复刻了SimpleDateFormat的行为,但又保留了DateTimeFormatter的类型安全和线程安全特性。

内容的提问来源于stack exchange,提问作者Martin Fernau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 15:37:34