I\'m trying to understand two things:
SimpleDateFormat
is not lenient)SimpleDateFormat API:
For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.
As for lenient, when it's set to false parse throws exception for invalid dates, eg 01/32/12, while in lenient mode this date is treated as 02/01/12. SimpleDateFormat uses Calendar internally, details about leniency can be found in Calendar API.
Question 1. This is a partial duplicate of Why Does Java's SimpleDateFormat parse this. The second answer on the question answers this nicely. The crux of it is this:
Number: For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields. Year: During parsing, only strings consisting of exactly two digits […] will be parsed into the default century. Any other numeric string, such as a one digit string, a three or more digit string, or a two digit string that isn't all digits (for example, "-1"), is interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the same pattern
Question 2. Look carefully: your input format is not the same as the format that you are passing to the function.
new SimpleDateFormat("dd/MM/yyyy");
vs.
format.parse("01/01/13");
Either parse to 01/01/2013
or use the date forat 'dd/MM/yy'
.
Use java.time, the modern Java date and time API, and the exception you expected comes sure thing:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String strToParse = "01/01/13";
LocalDate date = LocalDate.parse(strToParse, dateFormatter);
Result:
Exception in thread "main" java.time.format.DateTimeParseException: Text '01/01/13' could not be parsed at index 6 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948) at java.base/java.time.LocalDate.parse(LocalDate.java:428)
If you scroll right, you will see that the exception message mentions “could not be parsed at index 6”. Index 6 in the string is where the two digit year stands where four digits were expected.
When this question was asked nearly 7 years ago, using SimpleDateFormat
and Date
was acceptable. They were always poorly designed, and their replacement came out 7 months after the question was asked, so they are now considered long outdated. I warmly recommend using java.time instead.
Oracle tutorial: Date Time explaining how to use java.time.
According to the SimpleDateFormat javadoc for JDK 1.6,
For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields.
A look at the source code for the method that does the work, SimpleDateFormat.parse(String, ParsePosition)
, confirms this. There is a variable obeyCount
that is true if the pattern has no delimiters, like "yyyyMMdd", and false otherwise. With your pattern the parser looks for 3 numbers separated by 2 delimiters and does not care about the number of digits in each position.
The answers to your questions:
Lenient
is not a factor when delimiters are used.