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

Java8日期解析遇2位毫秒报错DateTimeParseException的解决方法

解决Java 8 DateTimeFormatter兼容2/3位毫秒的日期解析问题

这个问题很常见——Java 8的DateTimeFormatter默认采用严格匹配模式,你当前使用的"yyyy-MM-dd HH:mm:ss.SSS"模式要求毫秒部分必须是3位数字,所以遇到只有2位的10.77时,解析器在索引20的位置找不到第三位数字,就会抛出DateTimeParseException。

下面给你两种可靠的解决方案,优先推荐第一种,灵活性更高:


方案1:用DateTimeFormatterBuilder自定义毫秒位数范围

通过DateTimeFormatterBuilder的appendFraction方法,你可以指定毫秒部分的最小和最大允许位数,同时兼容2位和3位毫秒的场景:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

public class DateParseDemo {
    public static void main(String[] args) {
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                // 拼接固定的日期时间格式部分
                .appendPattern("yyyy-MM-dd HH:mm:ss")
                // 配置毫秒字段:最小2位,最大3位,允许可选小数点(适配你的输入场景)
                .appendFraction(ChronoField.MILLI_OF_SECOND, 2, 3, true)
                .toFormatter();

        // 测试3位毫秒的日期
        LocalDateTime dt1 = LocalDateTime.parse("2018-04-12 15:12:32.999", formatter);
        // 测试2位毫秒的日期
        LocalDateTime dt2 = LocalDateTime.parse("2018-04-18 15:27:10.77", formatter);

        System.out.println("3位毫秒解析结果:" + dt1); // 输出2018-04-12T15:12:32.999
        System.out.println("2位毫秒解析结果:" + dt2); // 输出2018-04-18T15:27:10.770
    }
}

参数说明:

  • ChronoField.MILLI_OF_SECOND:明确指定要处理的是毫秒字段
  • 2:允许的最小毫秒位数(适配你的2位毫秒场景)
  • 3:允许的最大毫秒位数(兼容原有的3位毫秒格式)
  • true:表示小数点为可选(如果业务中还有不带毫秒的日期,可以把最小位数改成0,实现无毫秒、2位、3位毫秒的全兼容)

方案2:切换到宽松解析模式(局限性较大)

如果你不想用Builder,也可以尝试将解析器设置为宽松模式,但这种方式兼容性不如方案1,依赖解析器的宽松规则,可能出现意外行为:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;

public class LenientParseDemo {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
                .withResolverStyle(ResolverStyle.LENIENT);

        LocalDateTime dt2 = LocalDateTime.parse("2018-04-18 15:27:10.77", formatter);
        System.out.println(dt2); // 输出2018-04-18T15:27:10.770
    }
}

注意:宽松模式会允许更多不严格的匹配,但如果输入的毫秒位数超过3位,它会自动截断,所以如果你的业务场景只有2位和3位毫秒,方案1是更稳妥的选择。


总结来说,核心问题是默认的SSS模式严格要求3位数字,通过DateTimeFormatterBuilder自定义位数范围是最灵活可靠的解决方式,能完美适配你的场景。

内容的提问来源于stack exchange,提问作者Prasad Krishnegowda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:43:55