SimpleDateFormat.parse 未检测到不正确的日期

SimpleDateFormat.parse not detecting incorrect date

一直在试验 SimpleDateFormat。我不明白的一件事:为什么以下 returns ok ?

String pattern = "MM/dd/yyyy";
SimpleDateFormat format = new SimpleDateFormat(pattern);

String input = "2023/03/22";
Date d = null;

try {
    d = format.parse(input);
} catch (ParseException e) {
    System.out.println("nok");
}

System.out.println("ok");

返回的日期也很荒谬:Fri Jul 03 00:00:00 CET 190

非常感谢任何解释!

让我们为那些想要答案的读者拼写出来:

format.setLenient(false) 就是你需要的。

以下是您的操作方法。我同意 AxelH:你应该使用 JDK8,java.time 包和 LocalTime:

import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateFormatTest {

    @Test(expected = ParseException.class)
    public void testSetLenient_IncorrectDateInput() throws ParseException {
        // setup
        String input = "2023/03/22";
        String pattern = "MM/dd/yyyy";
        DateFormat format = new SimpleDateFormat(pattern);
        format.setLenient(false);
        // exercise and assert
        format.parse(input);
    }
}

Any explanation is greatly appreciated!

我们开始: 解释很简单:

这种格式 "MM/dd/yyyy" 很简单,对象需要解析月日年信息。

所以你给了这个 "2023/03/22",那么这里的第一个错误是飞蛾(应该在 1 到 12 之间)持有值 2023,解析器将其解释为 12 月 + 2011 月之后的额外月份。

第 3 天没问题,第 22 年就是这个意思,即克里斯托出生后第 22 年。

所以你的结果日期是

有效数据加上奇怪的偏移量,即

12/03/0022 + 2011 个月。

现在 2011 个月等于:167 年零 7 个月 所以我们算一下:

22年的12 03加上167年零7个月...然后你得到

7 月 3 日星期五 00:00:00 CET 190


解决方法:

format.setLenient(boolean);

查看文档以了解在这种情况下会抛出什么异常....