简体   繁体   English

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

[英]Why is the expected exception not thrown on parsing invalid date?

I get two strings and I must transform them into dates and show the difference in days between them.我得到两个字符串,我必须将它们转换为日期并显示它们之间的天数差异。 But I must throw an exception if one of the two dates is invalid.但如果两个日期之一无效,我必须抛出异常。

This is the code I have so far for this task:这是我迄今为止完成此任务的代码:

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();
        }
    }
}

But if I enter an invalid date like 02/29/2021 , it converts to 03/01/2021 instead of throwing the exception.但是如果我输入一个无效的日期,比如02/29/2021 ,它会转换为03/01/2021而不是抛出异常。

java.time时间

@MCEmperor how i can change my formatter to use LocalDate? @MCEmperor 我如何更改格式化程序以使用 LocalDate?

Like MCEmperor I recommend that you use java.time, the modern Java date and time API, for your date work.像 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();
        }
    }
}

Example session:示例会话:

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)

You may also notice in the code how much more natural and simple it is to calculate the number of days between the two dates.您可能还会注意到在代码中计算两个日期之间的天数更加自然和简单。

What went wrong in your code?你的代码出了什么问题?

But if I enter an invalid date like 02/29/2021 , it converts to 03/01/2021 instead of throwing the exception.但是如果我输入一个无效的日期,比如02/29/2021 ,它会转换为03/01/2021而不是抛出异常。

That's as designed.就是这样设计的。 And I agree with you, it's a confusing, surprising and unfortunate design.我同意你的看法,这是一个令人困惑、令人惊讶和不幸的设计。 When you pass February 29 in a non-leap year to a SimpleDateFormat with default settings, it just takes it as the day after February 28, that is, March 1. It's just one of very many reasons not to use that class.当您将非闰年的 2 月 29 日传递给具有默认设置的SimpleDateFormat时,它只会将其视为 2 月 28 日之后的一天,即 3 月 1 日。这只是不使用该类的众多原因之一。

Link关联

Oracle tutorial: Date Time explaining how to use java.time. Oracle 教程:解释如何使用 java.time 的日期时间

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM