Java 8 DateTimeFormatter解析无时间日期字符串报错问题
问题根源与解决方案
你遇到的问题核心很明确:LocalDateTime要求必须同时包含日期和时间信息,当你解析纯日期字符串时,解析结果只包含了日期部分(对应LocalDate的信息),缺少时间相关的字段(时、分、秒),所以JDK无法从这个不完整的TemporalAccessor实例构造出LocalDateTime对象,这就是抛出DateTimeParseException的原因。
哪怕你用纯日期格式"dd/MM/yyyy"去解析LocalDateTime也会报错,本质也是一样的——这个格式只能解析出日期,没有时间字段,满足不了LocalDateTime的构造条件。
下面给你几种可行的解决方案:
方案1:捕获异常,降级解析为LocalDate再转LocalDateTime
这种方式比较直观,先尝试按带时间的格式解析,失败的话就按纯日期解析,再给它加上默认的起始时间(比如00:00:00):
String input = "13/12/2017"; // 也可以换成带时间的"13/12/2017 15:39:51" DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy[ HH:mm:ss]"); LocalDateTime localDateTime; try { localDateTime = LocalDateTime.parse(input, formatter); } catch (DateTimeParseException e) { // 解析纯日期,再转为带默认时间的LocalDateTime LocalDate localDate = LocalDate.parse(input, formatter); localDateTime = localDate.atStartOfDay(); } // 测试输出 System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))); System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
方案2:用DateTimeFormatterBuilder设置时间默认值
这种方式更优雅,不需要捕获异常,直接通过构建器给时间字段设置默认值,当输入没有时间部分时,会自动填充这些默认值:
DateTimeFormatter formatter = new DateTimeFormatterBuilder() // 先添加日期格式 .appendPattern("dd/MM/yyyy") // 标记时间部分为可选 .optionalStart() .appendPattern(" HH:mm:ss") .optionalEnd() // 给时间字段设置默认值 .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) .toFormatter(); // 两种输入都能正常解析 LocalDateTime dtWithTime = LocalDateTime.parse("13/12/2017 15:39:51", formatter); LocalDateTime dtOnlyDate = LocalDateTime.parse("13/12/2017", formatter); System.out.println(dtWithTime); // 输出:2017-12-13T15:39:51 System.out.println(dtOnlyDate); // 输出:2017-12-13T00:00
补充说明
为什么带时间的字符串能正常解析?因为此时解析后的TemporalAccessor包含了日期和时间的所有必填字段(年、月、日、时、分、秒),完全满足LocalDateTime的构造要求,所以不会报错。
内容的提问来源于stack exchange,提问作者tweetysat
相关产品推荐
相关产品推荐

