java.time
The question and the accepted answer use the java.util
date-time API and their formatting API, SimpleDateFormat
which was the right thing to do in 2013. In March 2014, the modern Date-Time API supplanted the legacy date-time API and since then it is strongly recommended to switch to java.time
, the modern date-time API.
Solution using java.time
, the modern Date-Time API:
The java.time
is smart to catch most such problems without any explicit settings. A custom DateTimeFormatter
is by default set to ResolverStyle#SMART
which does not allow a month outside the range 1-12 or a day-of-month value beyond 31. However, it also means that 02/31/2022
can be parsed to 2022-02-28
with a DateTimeFormatter.ofPattern("MM/dd/uuuu")
. It is only to disallow such a parsing that you need to set ResolverStyle.#STRICT
.
Demo:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;
class Main {
public static void main(String[] args) {
DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM/dd/uuuu", Locale.ENGLISH);
String arr[] = {
"120/12/2013", // 120 will be discarded against MM
"23/12/2013", // Month can not be outside the range 1-12
"Jan/12/2013", // Jan will discarded against MM. Requires MMM
"12/31/2022", // Will be parsed normally
"02/31/2022" // Will be parsed to 2022-02-28
};
for (String s : arr) {
try {
System.out.println("===========================");
System.out.println("Trying to parse " + s + " using the format MM/dd/uuuu");
System.out.println("Parsed to " + LocalDate.parse(s, parser));
} catch (DateTimeParseException e) {
System.out.println(e.getMessage());
// throw e;
}
}
}
}
Output:
===========================
Trying to parse 120/12/2013 using the format MM/dd/uuuu
Text '120/12/2013' could not be parsed at index 2
===========================
Trying to parse 23/12/2013 using the format MM/dd/uuuu
Text '23/12/2013' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 23
===========================
Trying to parse Jan/12/2013 using the format MM/dd/uuuu
Text 'Jan/12/2013' could not be parsed at index 0
===========================
Trying to parse 12/31/2022 using the format MM/dd/uuuu
Parsed to 2022-12-31
===========================
Trying to parse 02/31/2022 using the format MM/dd/uuuu
Parsed to 2022-02-28
ONLINE DEMO
Demo of ResolverStyle.#STRICT
:
class Main {
public static void main(String[] args) {
DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM/dd/uuuu", Locale.ENGLISH)
.withResolverStyle(ResolverStyle.STRICT);
String arr[] = {
"12/31/2022", // Will be parsed normally
"02/31/2022" // Will fail against ResolverStyle.STRICT check
};
for (String s : arr) {
try {
System.out.println("===========================");
System.out.println("Trying to parse " + s + " using the format MM/dd/uuuu");
System.out.println("Parsed to " + LocalDate.parse(s, parser));
} catch (DateTimeParseException e) {
System.out.println(e.getMessage());
// throw e;
}
}
}
}
Output:
===========================
Trying to parse 12/31/2022 using the format MM/dd/uuuu
Parsed to 2022-12-31
===========================
Trying to parse 02/31/2022 using the format MM/dd/uuuu
Text '02/31/2022' could not be parsed: Invalid date 'FEBRUARY 31'
ONLINE DEMO
Note: Here, you can use y
instead of u
but I prefer u
to y
.
Learn more about the modern Date-Time API from Trail: Date Time.