SimpleDateFormat is a very kind parser that rolls the resulting date instead of throwing an error. How can I parse a date strictly without regexps etc?
fmt = new SimpleDateFormat("dd.MM.yyyy")
fmt.parse("10.11.2012") // it works
fmt.parse("10.1150.2012") // it works but it's unwanted
fmt.setLenient(false);
is what you're looking for.Unfortunately fmt.setLenient(false); will not achieve strict date formatting. It helps some, for example parsing "2010-09-01" using format "yyyyMMdd" will succeed if lenient==true, but the result is very bizarre: 2009/12/09.
Even if lenient==false parse() still acts lenient. "2010/01/5" is allowed for the pattern "yyyy/MM/dd". And data disagreement like "1999/2011" for the pattern "yyyy/yyyy" is tolerated (yielding 2011). Garbage is also allowed after the pattern match. For example: "20100901" and "20100901andGarbage" will both match "yyyyMMdd".
I have written an extension of SimpleDateFormat that enforces strict pattern matching. You can find it here:
SimpleDateFormat.parse() ignores the number of characters in pattern
In my version format() and parse() are functional inverses. This is what I think most people would expect.
java.time
You can also use the java.time package in Java 8 and later (Tutorial). Its parsing strictly checks the date values.
For example:
Gives directly: