简体   繁体   中英

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.

java.time

@MCEmperor how i can change my formatter to use LocalDate?

Like MCEmperor I recommend that you use java.time, the modern Java date and time API, for your date work.

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.

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.

Link

Oracle tutorial: Date Time explaining how to use java.time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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