使用Java Time在Predicate中解析日期时间字符串为日期时报错如何解决
错误原因
- 日期模式顺序不匹配:你定义的
DateTimeFormatter为dd/MM/yyyy(日/月/年),但实际待解析的字符串替换-为/后为2008/04/11 00:00:00,前四位为年份,顺序为年/月/日,和定义的模式完全不匹配,因此在索引2位置解析失败。 - 待解析内容包含多余字段:你使用
LocalDate.parse仅需解析日期部分,但原始字符串后缀带有00:00:00的时间内容,没有对应的匹配规则,也会触发解析异常。
解决方案
方案1:直接适配原始字符串格式(推荐,无需字符替换)
直接匹配CSV中原始的yyyy-MM-dd HH:mm:ss格式即可,不需要额外做字符替换,性能和可读性更好:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); Predicate<Client> clientBirth = p -> Period.between( LocalDate.parse(p.getBirth(), formatter), LocalDate.now() ).getYears() >= 100;
方案2:保留替换逻辑,修正模式并截断时间部分
如果需要保留-替换为/的逻辑,先截断字符串的时间部分,同时修改日期模式为年/月/日的顺序:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); Predicate<Client> clientBirth = p -> { // 截取空格前的日期部分,再做字符替换 String pureDate = p.getBirth().split(" ")[0].replaceAll("-", "/"); return Period.between(LocalDate.parse(pureDate, formatter), LocalDate.now()).getYears() >= 100; };
优化建议
如果CSV中可能存在空值、格式异常的日期数据,可增加异常捕获逻辑,避免整个流处理中断,同时可以直接标记格式异常的数据为录入错误:
Predicate<Client> clientBirth = p -> { try { if (p.getBirth() == null || p.getBirth().isBlank()) { // 空值判定为录入错误 return true; } DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDate birthDate = LocalDate.parse(p.getBirth(), formatter); return Period.between(birthDate, LocalDate.now()).getYears() >= 100; } catch (DateTimeParseException e) { // 格式异常判定为录入错误 return true; } };
内容的提问来源于stack exchange,提问作者Adalberto J. Brasaca
相关产品推荐
相关产品推荐

