You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何ParseException未被捕获?Java日期校验异常排查

问题解答

1. 字母年份抛出异常却仍生成Worker的原因

你的isThisDateValid方法已经正确捕获了ParseException(控制台打印的异常栈就是证据),最终还是生成Worker对象的问题出在main方法的逻辑——你没有利用该方法的返回值做判断,不管验证是否通过,都直接用用户输入的年份字符串创建了Worker。

比如你的main方法大概率是类似这样的逻辑:

Scanner scanner = new Scanner(System.in);
System.out.println("Enter name:");
String name = scanner.nextLine();
System.out.println("Enter position:");
String position = scanner.nextLine();
System.out.println("Enter year");
String year = scanner.nextLine();

// 调用了验证,但没用到返回值
isThisDateValid(year, "yyyy");
// 直接创建Worker,不管验证结果
Worker worker = new Worker(name, position, year);
System.out.println(worker);

改成以下逻辑即可解决:

// 调用验证后根据结果处理
if (isThisDateValid(year, "yyyy")) {
    Worker worker = new Worker(name, position, year);
    System.out.println(worker);
} else {
    System.out.println("年份格式错误,请重新输入");
}

2. 超长数字年份被接受的原因

SimpleDateFormat.setLenient(false)的作用是关闭宽松日期解析,比如拒绝2月30日、13月这种非法日期,但它不会限制年份的数字长度——yyyy格式本身就支持任意位数的数字年份,所以20023这种5位数字会被当成合法年份解析。

如果要限制年份必须是4位数字,需要额外添加正则校验:

// 在isThisDateValid方法开头增加校验
if (!dateToValidate.matches("\\d{4}")) {
    return false;
}

修正后的完整验证方法

public class Main {

    public static boolean isThisDateValid(String dateToValidate, String dateFormat) {
        if (dateToValidate == null) {
            return false;
        }
        // 先校验年份为4位数字
        if (!dateToValidate.matches("\\d{4}")) {
            return false;
        }

        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        sdf.setLenient(false);

        try {
            Date date = sdf.parse(dateToValidate);
        } catch (ParseException exc) {
            exc.printStackTrace();
            return false;
        }

        return true;
    }
}

进阶建议:改用Java 8+的DateTimeFormatter

SimpleDateFormat是线程不安全的,推荐使用Java 8引入的DateTimeFormatter,它的校验更严谨,用法也更清晰:

public static boolean isThisDateValid(String dateToValidate) {
    if (dateToValidate == null || !dateToValidate.matches("\\d{4}")) {
        return false;
    }
    // 严格模式解析
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu")
            .withResolverStyle(ResolverStyle.STRICT);
    try {
        // 拼接月日确保完整日期解析
        LocalDate.parse(dateToValidate + "-01-01", formatter);
        return true;
    } catch (DateTimeParseException e) {
        e.printStackTrace();
        return false;
    }
}

内容的提问来源于stack exchange,提问作者Ievgeniia Leleka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 17:35:02