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

如何用一个DateTimeFormatter解析带可选秒的yyyyMMddHHmmss格式时间?

问题:解析带可选秒的日期字符串失败

需要解析格式为yyyyMMddHHmmss的日期,其中秒(ss)部分是可选的,202308301000(12位)和20230830100005(14位)均为合法输入。

定义了如下格式化器:

private static final DateTimeFormatter INPUT_FORMATTER = new DateTimeFormatterBuilder()
    .appendPattern("yyyyMMddHHmm")
    .optionalStart()
    .appendPattern("ss")
    .optionalEnd()
    .toFormatter();

但解析带秒的字符串时抛出异常:

INPUT_FORMATTER.parse("202308301000"); // 执行正常
INPUT_FORMATTER.parse("20230830100005"); // 抛出异常

异常信息:

Exception in thread "main" java.time.format.DateTimeParseException: Text '20230830100005' could not be parsed at index 0

解决方案

问题根源在于appendPattern("yyyyMMddHHmm")的使用逻辑:该方法会将整个12位的模式作为一个完整单元匹配,当解析14位字符串时,解析器会先消耗前12位完成匹配,剩余的2位无法被后续的可选ss段处理,导致解析失败。

以下两种方法可解决该问题:

方式一:使用带可选段的简化模式字符串

无需借助DateTimeFormatterBuilder,直接在模式中用方括号[]标记秒部分为可选:

private static final DateTimeFormatter INPUT_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmm[ss]");

方式二:通过DateTimeFormatterBuilder逐个指定字段长度

如果需要更精细的字段控制,可通过appendValue明确每个字段的固定长度,并将秒字段设为可选:

private static final DateTimeFormatter INPUT_FORMATTER = new DateTimeFormatterBuilder()
    .appendValue(ChronoField.YEAR, 4)
    .appendValue(ChronoField.MONTH_OF_YEAR, 2)
    .appendValue(ChronoField.DAY_OF_MONTH, 2)
    .appendValue(ChronoField.HOUR_OF_DAY, 2)
    .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
    .optionalStart()
    .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
    .optionalEnd()
    .toFormatter();

两种方案均能同时正确解析12位(无秒)和14位(带秒)的日期字符串。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 18:03:14