为什么在解析无效日期时没有抛出预期的异常?



我得到两个字符串,我必须将它们转换为日期并显示它们之间的天数差异。但是如果两个日期中有一个无效,我必须抛出一个异常。

这是我到目前为止为这个任务编写的代码:

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String d1 = sc.next();
String d2 = sc.next();
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
try {
Date date1 = formatter.parse(d1);
Date date2 = formatter.parse(d2);
long dt = (date1.getTime() - date2.getTime()) + 3600000;
long days = (dt / 86400000L);
System.out.println(days);
} catch (ParseException e) {
System.out.println("Data inválida");
e.printStackTrace();
}
}
}

但是如果我输入一个无效的日期,比如02/29/2021,它会转换为03/01/2021,而不是抛出异常。

java.time

@MCEmperor我如何改变我的格式化器使用LocalDate?

像MCEmperor一样,我建议你使用java。time,现代Java日期和时间API,用于您的日期工作。
public class Main {
private static final DateTimeFormatter FORMATTER
= DateTimeFormatter.ofPattern("dd/MM/uuuu", Locale.ROOT)
.withResolverStyle(ResolverStyle.STRICT);
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String d1 = sc.next();
String d2 = sc.next();

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 dtpe) {
System.out.println("Data inválida");
dtpe.printStackTrace();
}
}
}

会话示例:

03/02/2021
02/29/2021
Data inválida
java.time.format.DateTimeParseException: Text '02/29/2021' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 29
at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:2017)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952)
at java.base/java.time.LocalDate.parse(LocalDate.java:428)
at Main.main(Main.java:18)

您可能还注意到,在代码中计算两个日期之间的天数要自然和简单得多。

你的代码出了什么问题?

但如果我输入一个无效的日期,如02/29/2021,它转换为03/01/2021而不是抛出异常。

这是设计好的。我同意你的观点,这是一个令人困惑、令人惊讶和不幸的设计。当您将非闰年的2月29日传递给具有默认设置的SimpleDateFormat时,它只会将其作为2月28日之后的第一天,即3月1日。这只是不使用这个类的众多原因之一。

链接Oracle tutorial: Date Time using java.time.

最新更新