使用HH:mm E d MMM YYYY模式解析DateTimeFormatter失败求助
解决DateTimeParseException的问题
我来帮你排查一下问题所在,你的代码里有几个关键错误导致了解析失败:
错误原因分析
- 多余的年份占位符:你在格式字符串里加了
YYYY,但输入的14:30 Sat 05 May根本没有年份信息。解析器读到May之后还在找年份,自然会在索引16的位置抛出异常。 - 缺少英文Locale指定:
Sat和May是英文的星期、月份缩写,如果你的JVM默认Locale不是英文,解析器根本识别不了这些字符串,这也会引发解析失败。 YYYY的误用:就算需要年份,YYYY代表的是基于周的年份,日常日期解析应该用yyyy(普通公历年份),不过这里我们完全不需要在格式里包含年份。
修正后的解决方案
下面提供两种可行的写法,你可以根据需求选择:
方案一:自动使用当前年份
用DateTimeFormatterBuilder设置默认年份为当前年份,同时指定英文Locale确保解析正确:
import java.time.LocalDateTime; import java.time.Year; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.ChronoField; import java.util.Locale; public class DateParseExample { public static void main(String[] args) { String time = "14:30 Sat 05 May"; DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendPattern("HH:mm E dd MMM") // 设置默认年份为当前年份 .parseDefaulting(ChronoField.YEAR, Year.now().getValue()) .toFormatter(Locale.ENGLISH); LocalDateTime formatDateTime = LocalDateTime.parse(time, formatter); System.out.println(formatDateTime); } }
方案二:手动指定固定年份
如果你需要指定特定年份(比如你代码里的2018),可以先解析为TemporalAccessor,再手动构建LocalDateTime:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAccessor; import java.util.Locale; public class DateParseExample { public static void main(String[] args) { String time = "14:30 Sat 05 May"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm E dd MMM", Locale.ENGLISH); TemporalAccessor temporal = formatter.parse(time); LocalDateTime formatDateTime = LocalDateTime.of( 2018, // 指定目标年份 temporal.get(ChronoField.MONTH_OF_YEAR), temporal.get(ChronoField.DAY_OF_MONTH), temporal.get(ChronoField.HOUR_OF_DAY), temporal.get(ChronoField.MINUTE_OF_HOUR) ); System.out.println(formatDateTime); } }
额外注意点
- 格式里的
dd对应两位日期(比如05),如果输入可能出现一位日期(比如5),可以改成d,两种格式都能兼容。 - 始终指定Locale可以避免不同环境下的解析问题,尤其是处理英文日期字符串时。
内容的提问来源于stack exchange,提问作者RoRo88
相关产品推荐
相关产品推荐

