使用DateTimeFormatter解析含可选时间的字符串时,移除空格即解析失败
解决LocalDateTime解析连续日期时分秒字符串的问题
嘿,我明白你遇到的困惑了——同样是可选模式,带空格的能正常解析,不带空格的就报错,确实有点让人摸不着头脑。我来帮你拆解一下问题,并给出靠谱的解决方案。
问题根源
当你用yyyyMMdd[HHmmss]这种模式时,虽然理论上它表示“8位日期+可选的6位时分秒”,但DateTimeFormatter对连续无分隔符的可选模式匹配逻辑,在结合parseDefaulting时可能会出现识别偏差。而带空格的模式yyyyMMdd[ HHmmss]能正常工作,是因为空格作为明确的分隔符,让解析器清晰区分了必选的日期部分和可选的时分秒部分,不会产生歧义。
靠谱的解决方案
改用DateTimeFormatterBuilder的optionalStart()和optionalEnd()方法来包裹可选的时分秒部分,这种方式比在模式字符串里用方括号更稳定,能完美支持8位纯日期和14位日期+时分秒的两种字符串:
// 构建同时支持两种格式的格式化器 DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendPattern("yyyyMMdd") // 必选的8位日期部分 .optionalStart() // 标记可选部分开始 .appendPattern("HHmmss") // 可选的6位时分秒部分 .optionalEnd() // 标记可选部分结束 // 给时分秒设置默认值,当字符串只有日期时生效 .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) .toFormatter(); // 测试两种字符串 LocalDateTime dateOnly = LocalDateTime.parse("20120301", formatter); LocalDateTime dateTime = LocalDateTime.parse("20120301122133", formatter); System.out.println(dateOnly); // 输出:2012-03-01T00:00 System.out.println(dateTime); // 输出:2012-03-01T12:21:33
为什么这个方法有效?
optionalStart()和optionalEnd()明确告诉解析器:这部分内容是可选的,能匹配就匹配,匹配不上就用默认值填充。这种方式的逻辑更清晰,不会因为连续字符导致解析器的匹配逻辑混乱,比模式字符串里的方括号兼容性更好。
内容的提问来源于stack exchange,提问作者Kamil Roman
相关产品推荐
相关产品推荐

