What the follow does is, tests to see if a given format can parse the String
to a LocalDate
OR LocalDateTime
. If it can (do either), it will the compare the result of formatting either of those results against the original input, just to be sure (because date/time handling is just so much fun).
The intention is to not just determine if the values are within the specified formats, but also to verify if they are actually valid date/time values, because 99/99/0000
is a valid format, but isn't a valid date (except to SimpleDateFormat
♂️)
The parsing and comparisons are case insensitive.
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.util.Locale;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
String[] formats = new String[] {
"dd/MM/yyyy",
"dd-MM-yyyy",
"d MMMM yyyy"
};
String[] values = new String[] {
"03/03/2000",
"03-03-2000",
"3rd march 2000"
};
for (String value : values) {
String fixedValue = value.replaceAll("(?<=\\d)(st|nd|rd|th)", "");
boolean isValid = isValid(formats, fixedValue, Locale.ENGLISH);
System.out.println(value + " is valid = " + isValid);
}
}
public boolean isValid(String[] formats, String value, Locale locale) {
for (String format : formats) {
if (isValidDate(format, value, locale) || isValidDateTime(format, value, locale)) {
return true;
}
}
return false;
}
public boolean isValid(String format, String value, Locale locale) {
return isValidDate(format, value, locale) || isValidDateTime(format, value, locale);
}
public boolean isValidDateTime(String format, String value, Locale locale) {
try {
DateTimeFormatter fomatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern(format)
.toFormatter(locale);
LocalDateTime ldt = LocalDateTime.parse(value, fomatter);
return ldt.format(fomatter).equalsIgnoreCase(value);
} catch (DateTimeParseException | java.time.temporal.UnsupportedTemporalTypeException exp) {
return false;
}
}
public boolean isValidDate(String format, String value, Locale locale) {
try {
DateTimeFormatter fomatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern(format)
.toFormatter(locale);
LocalDate ld = LocalDate.parse(value, fomatter);
return ld.format(fomatter).equalsIgnoreCase(value);
} catch (DateTimeParseException | java.time.temporal.UnsupportedTemporalTypeException exp) {
return false;
}
}
}
which outputs
03/03/2000 is valid = true
03-03-2000 is valid = true
3rd march 2000 is valid = true
ps: Thanks Dev Parzival for the regular expression, that save a lot of time