First and second post on the same subject. This is such a great way to learn.
Once again I'm open to suggestions. I have implemented almost all of the suggestions from before, which have resulted in the code looking like this:
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
enum DateValidator {
DDMMYYYY(0, 2, 4),
MMDDYYYY(2, 0, 4),
YYYYMMDD(6, 4, 0);
private final int dayIndex;
private final int monthIndex;
private final int yearIndex;
private DateValidator(int dayIndex, int monthIndex, int yearIndex) {
this.dayIndex = dayIndex;
this.monthIndex = monthIndex;
this.yearIndex = yearIndex;
}
private int getDay(String date){ return Integer.parseInt(date.substring(dayIndex, dayIndex + 2)); }
private int getMonth(String date){ return Integer.parseInt(date.substring(monthIndex, monthIndex + 2)); }
private int getYear(String date){ return Integer.parseInt(date.substring(yearIndex, yearIndex + 4)); }
private static boolean isLeapYear(int y) {
return (y % 4 == 0) && ((y % 100 != 0) || (y % 400 == 0)); }
private boolean isDateLegal(String date) {
final int day = getDay(date);
final int month = getMonth(date);
final int year = getYear(date);
boolean isValid = false;
final Set<Integer> values = new HashSet<Integer>(Arrays.asList(1, 3, 5, 7, 8, 10, 12));
final int daysInFebruary = (month == 2 && isLeapYear(year)) ? 29 : 28;
if (day > 0) {
if (values.contains(month)) { isValid = day <= 31; }
else if (month > 0 && month < 13 && month != 2) { isValid = day <= 30; }
else if (month == 2) isValid = day <= daysInFebruary;
}
return isValid;
}
private static boolean isDateFormatValid(String date) {
final String DATE_PATTERN = "(^" + "[0-9]{2}\\.[0-9]{2}\\.[1-2][0-9]{3}|" +
"[0-9]{2}\\-[0-9]{2}\\-[1-2][0-9]{3}|" +
"[0-9]{2}\\/[0-9]{2}\\/[1-2][0-9]{3}|" +
"[0-9]{2}\\s[0-9]{2}\\s[1-2][0-9]{3}|" +
"[0-9]{2}[0-9]{2}[1-2][0-9]{3}|" +
"[1-2][0-9]{3}\\.[0-9]{2}\\.[0-9]{2}|" +
"[1-2][0-9]{3}\\-[0-9]{2}\\-[0-9]{2}|" +
"[1-2][0-9]{3}\\/[0-9]{2}\\/[0-9]{2}" +
"[1-2][0-9]{3}\\s[0-9]{2}\\s[0-9]{2}" +
"[1-2][0-9]{3}[0-9]{2}[0-9]{2}" +")$";
Pattern pattern = Pattern.compile(DATE_PATTERN);
Matcher matcher = pattern.matcher(date);
return matcher.matches();
}
public boolean validate(String date) {
return this.isDateLegal(date.replaceAll("[\\.\\-\\/\\s]", "")) && isDateFormatValid(date);
}
}
class Main {
public static void main(String[] args) {
System.out.print(DateValidator.DDMMYYYY.validate("16.10.1990") ? "Date is valid" : "Date is NOT valid");
}
}