java.time
I recommend that you use java.time, the modern Java date and time API, for your date work. Advantages in your particular case include that the formatter you need is already built in and it does throw the exception that you ask for.
For demonstration I am using this auxiliary method:
public static void tryToParse(String dateString) {
try {
LocalDate date
= LocalDate.parse(dateString, DateTimeFormatter.BASIC_ISO_DATE);
System.out.println(dateString + " -> " + date);
} catch (DateTimeParseException dtpe) {
System.out.println(dateString + ": " + dtpe.getMessage());
}
}
Trying it out:
// Valid date
tryToParse("20200507");
// Invalid date value
tryToParse("20210229");
// Text after date
tryToParse("20200623Q");
// Example from question
tryToParse("9450524Q");
Output is:
20200507 -> 2020-05-07
20210229: Text '20210229' could not be parsed: Invalid date 'February 29' as '2021' is not a leap year
20200623Q: Text '20200623Q' could not be parsed, unparsed text found at index 8
9450524Q: Text '9450524Q' could not be parsed at index 6
Please also enjoy the precise and helpful exception messages. What happened in the last case was: year 9450 and month 52 were parsed, but since 4Q
is not a valid two-digit date, the exception was thrown (before validating whether 52 is a valid month number).
What happened in your code
The SimpleDateFormat
class is a notorious troublemaker. You have discovered a central design problem with it, but certainly not the only one. What it did was: It parsed 4-digit year, 9450, and two-digit month, 52. There are 12 months in a year, but a SimpleDateFormat
with standard settings doesn’t care. It converts 48 of the months to 4 years and ends up in the 4th month 4 years later. Finally 4 is parsed as day of month. The remainder of the text, the Q
, is ignored.
As I see it your example exhibits three flaws of SimpleDateFormat
:
- With standard settings it is lenient, it accepts an invalid month number.
- When asked to parse two digits and finding only one, it settles with that one digit without reporting the error.
- In the case of unparseable text after the parsed text it does not report any error either.
Links