Define 'valid'.
The regex, for example, allows For the 39th day of the 19th month, as well as the 0th day of the 0th month: 39-19-0000
is a valid date according to it, but 1-1-2020
is not (only 01-01-2020
would be).
The SDF is old API that you shouldn't use (use java.time
), but as far as this code goes, lenience is turned off, so it does not accept 39-19-0000
, though it would accept 1-1-2020
.
Combining the two gets you the strictest take, but it sure feels convoluted. Is there a particular heinous issue with accepting 1-1-2020
?
But note this gigantic problem: Year confusion. 1-1-99
WILL parse with a .setLenient(false)
SDF with pattern dd.MM.yyyy
, and is interpreted as jan 1st during the year 99, sometime during the days of the roman empire (not like the prince song).
For that purpose alone, that regex is quite useful; you can use the regexp to error out if a 2-digit year is passed, as SDF can't reject that kind of input.
Thus, the real advice!
Those old date apis are so incredibly bad. They suck. Do not use them. Update your IDE, mark down SimpleDateFormat
as illegal. Here is the java time package, doing precisely what you want. Note that SDF returns a java.util.Date
which is a lying liar who lies: That represent an instant in time and has no business representing dates. It really doesn't - that's why all the various .getYear()
etc methods are deprecated.
LocalDate x = LocalDate.parse("01.01.1999", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
System.out.println(x);
> 1999-01-01
// Awesome. It's an actual _DATE_ and not a timestamp where timezones
// can mess everything up.
LocalDate x = LocalDate.parse("01.01.99", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
> Exception in thread "main" java.time.format.DateTimeParseException: Text '01.01.1999' could not be parsed
// perfect. it crashes, as it should.
LocalDate x = LocalDate.parse("1.1.1999", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
> Exception in thread "main" java.time.format.DateTimeParseException: Text '01.01.1999' could not be parsed
// if you want `1.1.1999` to crash, well, you can.
LocalDate x = LocalDate.parse("1.1.1999", DateTimeFormatter.ofPattern("d.M.yyyy"));
System.out.println(x);
> 1999-01-01
// but you don't have to. with just `d`, 1 parses as 1, so does 01.
You can go with yy
too, which FORCES that you only use 2 digits; they are all interpreted as 20xx. (1.1.99 is 2099-01-01).