java.time
java.time is a modern date and time Java interface that behaves as you expected. So this is a matter of simply translating your code:
private static final DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd.MM.yyyy"); private static final DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("dd-MM-yyyy"); private static final DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static LocalDate parseDate(String dateString) { LocalDate parsedDate; try { parsedDate = LocalDate.parse(dateString, formatter1); } catch (DateTimeParseException dtpe1) { try { parsedDate = LocalDate.parse(dateString, formatter2); } catch (DateTimeParseException dtpe2) { parsedDate = LocalDate.parse(dateString, formatter3); } } return parsedDate; }
(I placed the formatter outside of your method so that it would not be re-created for each call. You can put it inside if you want.)
Let's try this:
LocalDate date = parseDate("2013-01-31"); System.out.println(date);
Exit:
2013-01-31
For numbers, DateTimeFormatter.ofPattern takes the number of letters of the template as the minimum field width. Furthermore, it is assumed that the day of the month is never more than two digits. Thus, when trying to format dd-MM-yyyy he successfully parsed 20 as the day of the month, and then threw a DateTimeParseException because after 20 there was no hyphen (dash). Then the method continued to try the next formatter.
What went wrong in your code
The SimpleDateFormat class you tried to use is notoriously problematic and, fortunately, has long been deprecated. You have encountered one of many problems with this. Repeating an important sentence from the documentation on how it handles numbers from a Teetoo answer:
In parsing, the number of letters in the pattern is ignored unless it is necessary to separate two adjacent fields.
Thus, new SimpleDateFormat("dd-MM-yyyy") successfully parses 2013 as the day of the month, 01 as the month, and 31 as the year. Then we should have expected it to throw an exception, because in January 31 there were no 2013 days. But SimpleDateFormat with default settings does not. It just keeps counting the days over the next months and years and ends on July 5, 36, five and a half years later, the result you observed.
Link
Oracle Tutorial: Date Time explaining how to use java.time.
Ole VV May 26 '19 at 17:39 2019-05-26 17:39
source share