Java中yyyy-MM-dd为何能被yyyyMMdd格式的SimpleDateFormat解析成功?
为什么"yyyy-MM-dd"格式字符串能被"yyyyMMdd"的SimpleDateFormat解析成功?
这本质是SimpleDateFormat默认开启的宽松解析(lenient)模式导致的,具体解析逻辑如下:
当使用
"yyyyMMdd"模式解析"2023-01-01"时:- 先读取前4位数字
"2023"匹配yyyy; - 遇到非数字的
'-',宽松模式会自动跳过该字符; - 继续读取后续的
"01"匹配MM; - 再跳过下一个
'-',读取"01"匹配dd;
整个字符串解析完成,因此不会抛出异常。
- 先读取前4位数字
而使用
"yyyy/MM/dd"模式解析"2023-01-01"时:
模式中明确指定了分隔符为'/',解析到第一个'-'时,与模式要求的分隔符不匹配,即使在宽松模式下也无法跳过这种不匹配的分隔符,因此直接抛出ParseException。
验证与解决方法
如果想要严格匹配模式,避免这种“意外解析成功”的情况,可以关闭宽松模式:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); // 关闭宽松解析,启用严格模式 sdf.setLenient(false); try { Date date = sdf.parse("2023-01-01"); } catch (ParseException e) { // 此时会抛出预期的解析异常 e.printStackTrace(); }
另外,推荐使用Java 8及以上版本提供的DateTimeFormatter,它默认是严格解析,且线程安全:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); try { LocalDate date = LocalDate.parse("2023-01-01", formatter); } catch (DateTimeParseException e) { // 抛出异常,符合预期 e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者Karthik CM
相关产品推荐
相关产品推荐

