Java自定义Date类构造器中如何校验MM/DD/YY或MM/DD/YYYY日期格式?
高效实现日期格式校验的方案
方案1:正则匹配 + DateTimeFormatter解析(Java 8及以上推荐)
直接用Java 8引入的DateTimeFormatter来做格式校验和日期合法性验证,它会自动处理月份范围、对应月份的最大天数、闰年等细节,比手动拆分校验省心太多。
修改后的构造器代码示例:
import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.Arrays; import java.util.List; public class Date { // 定义支持的两种日期格式 private static final List<DateTimeFormatter> DATE_FORMATTERS = Arrays.asList( DateTimeFormatter.ofPattern("MM/dd/yy"), DateTimeFormatter.ofPattern("MM/dd/yyyy") ); public Date(String date) { if (date == null || date.trim().isEmpty()) { throw new IllegalArgumentException("请提供MM/DD/YY或MM/DD/YYYY格式的日期"); } boolean isValid = false; // 尝试用两种格式分别解析 for (DateTimeFormatter formatter : DATE_FORMATTERS) { try { LocalDate.parse(date, formatter); isValid = true; break; } catch (DateTimeParseException e) { // 当前格式不匹配,继续试下一个 continue; } } if (!isValid) { throw new IllegalArgumentException("日期格式无效,请使用MM/DD/YY或MM/DD/YYYY格式"); } } }
- 优势:不用手动写一堆判断月份、日期范围的逻辑,
DateTimeFormatter会自动校验所有合法性,代码简洁不易出错。 - 注意:
MM和dd必须是两位数字(比如1月要写01,不能写1),完全符合你要求的格式规范。
方案2:正则前置过滤(可选)
如果想先快速排除明显不符合格式的字符串,可以加一层正则匹配,减少后续解析的次数。不过上面的方案已经足够高效,这个属于优化选项。
可用的正则表达式:
private static final String DATE_REGEX = "^(0[1-9]|1[012])/(0[1-9]|[12][0-9]|3[01])/(\\d{2}|\\d{4})$";
在构造器里先做判断:
if (!date.matches(DATE_REGEX)) { throw new IllegalArgumentException("日期格式无效,请使用MM/DD/YY或MM/DD/YYYY格式"); }
- 注意:正则只能校验格式(比如月份是1-12的两位数字),没法识别2月30号、4月31号这类逻辑无效的日期,所以必须结合日期解析做最终校验。
方案3:旧版SimpleDateFormat(兼容Java 7及以下)
如果项目还在用Java 7或更早版本,可以用SimpleDateFormat,但要注意它不是线程安全的,每次解析都要新建实例,并且必须开启严格模式:
import java.text.ParseException; import java.text.SimpleDateFormat; public class Date { public Date(String date) { if (date == null || date.trim().isEmpty()) { throw new IllegalArgumentException("请提供MM/DD/YY或MM/DD/YYYY格式的日期"); } SimpleDateFormat sdfShort = new SimpleDateFormat("MM/dd/yy"); SimpleDateFormat sdfLong = new SimpleDateFormat("MM/dd/yyyy"); // 开启严格模式,禁止自动转换无效日期 sdfShort.setLenient(false); sdfLong.setLenient(false); boolean isValid = false; try { sdfShort.parse(date); isValid = true; } catch (ParseException e) { try { sdfLong.parse(date); isValid = true; } catch (ParseException ex) { // 两种格式都不匹配 } } if (!isValid) { throw new IllegalArgumentException("日期格式无效,请使用MM/DD/YY或MM/DD/YYYY格式"); } } }
- 关键:必须调用
setLenient(false),否则SimpleDateFormat会把02/30/2024这种无效日期自动转成03/01/2024,完全起不到校验作用。
内容的提问来源于stack exchange,提问作者Mr.Moffia
相关产品推荐
相关产品推荐

