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

为什么使用SimpleDateFormat解析无效日期未抛出预期异常?

问题原因

SimpleDateFormat默认开启了*宽松解析(lenient parsing)*模式,这种模式下会自动调整逻辑上不合法的日期为合法值,不会抛出解析异常,这就是你输入02/29/2021会被自动转为03/01/2021的核心原因。

修复方案

方案1:调整SimpleDateFormat的解析模式

只需要在初始化SimpleDateFormat后,调用setLenient(false)关闭宽松解析即可,代码修改如下:

SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
// 新增下面这行,关闭宽松解析
formatter.setLenient(false);

注意:SimpleDateFormat是线程不安全的类,如果是多线程环境下使用要注意加锁或者用线程本地变量存储,避免出现并发问题。

方案2(更推荐):使用Java 8+提供的java.time新时间API

Java 8之后推出的java.time包彻底解决了旧日期API的线程安全、解析逻辑不严谨的问题,默认就是严格解析模式,不需要额外配置,实现代码参考:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Scanner;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String d1 = sc.next();
        String d2 = sc.next();
        // 定义日期格式,默认就是严格解析
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");

        try {
            LocalDate date1 = LocalDate.parse(d1, formatter);
            LocalDate date2 = LocalDate.parse(d2, formatter);
            // 直接计算天数差,不需要手动处理时间戳
            long days = ChronoUnit.DAYS.between(date2, date1);
            System.out.println(days);
        } catch (DateTimeParseException e) {
            System.out.println("Data inválida");
            e.printStackTrace();
        }
    }
}

这个方案不需要额外配置严格解析,遇到02/29/2021这类无效日期会直接抛出DateTimeParseException,而且API设计更清晰,不存在线程安全问题。

内容的提问来源于stack exchange,提问作者Robson Fischer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 15:48:02