TL; dr
Use strict mode on java.time.DateTimeFormatter to parse LocalDate . Trap for DateTimeParseException .
LocalDate.parse( // Represent a date-only value, without time-of-day and without time zone. "31/02/2000" , // Input string. DateTimeFormatter // Define a formatting pattern to match your input string. .ofPattern ( "dd/MM/uuuu" ) .withResolverStyle ( ResolverStyle.STRICT ) // Specify leniency in tolerating questionable inputs. )
After parsing, you can check for an acceptable cost. For example, the date of birth for the last hundred years.
birthDate.isAfter( LocalDate.now().minusYears( 100 ) )
Avoid obsolete date and time classes
Avoid using the problematic old date and time classes that ship with the earliest versions of Java. Now superseded by java.time classes.
LocalDate & DateTimeFormatter & ResolverStyle
The LocalDate class represents a value only for a date without a time of day and without a time zone.
String input = "31/02/2000"; DateTimeFormatter f = DateTimeFormatter.ofPattern ( "dd/MM/uuuu" ); try { LocalDate ld = LocalDate.parse ( input , f ); System.out.println ( "ld: " + ld ); } catch ( DateTimeParseException e ) { System.out.println ( "ERROR: " + e ); }
The java.time.DateTimeFormatter class can be configured to parse strings in any of the three indulgence modes defined in the ResolverStyle enumeration. We insert a line into the code above to try each of the modes.
f = f.withResolverStyle ( ResolverStyle.LENIENT );
Results, achievements:
ResolverStyle.LENIENT
ld: 2000-03-02ResolverStyle.SMART
ld: 2000-02-29ResolverStyle.STRICT
ERROR: java.time.format.DateTimeParseException: text "31/02/2000" cannot be parsed: invalid date "FEBRUARY 31"
We see that in ResolverStyle.LENIENT mode, an invalid date moves an equivalent number of days in advance. In ResolverStyle.SMART mode (by default), a logical decision is made to save the date in the month and switch to the last possible day of the month, February 29, in a leap year, since this month does not have a 31st day. The ResolverStyle.STRICT mode throws an exception stating that there is no such date.
All three of them are reasonable depending on your business problem and policy. It seems that in your case, you want strict mode to reject the wrong date, rather than correct it.
About java.time
The java.time framework is built into Java 8 and later. These classes supersede the nasty old obsolete date and time classes, such as java.util.Date , Calendar , and SimpleDateFormat .
The Joda-Time project, currently in maintenance mode , recommends switching to the java.time classes.
To learn more, see the Oracle Tutorial . And a search for many examples and explanations. JSR 310 specification .
You can exchange java.time objects directly with your database. Use a JDBC driver that conforms to JDBC 4.2 or later. No strings needed, no java.sql.* Needed.
Where to get java.time classes?
- Java SE 8 , Java SE 9 and later
- Built in.
- Part of the standard Java API with integrated implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and Java SE 7
- Most of the functionality of java.time has been ported to Java 6 and 7 in ThreeTen-Backport .
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier versions of Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP ....
The ThreeTen-Extra project extends java.time with additional classes. This project is a testing ground for possible future additions to java.time. Here you can find some useful classes such as Interval , YearWeek , YearQuarter and others .