The task is following:
Build the regular expression for following validation: a) Date (Format: DD.MM.YYYY)
I wrote the following code:
package validator.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Validator {
public static boolean checkDateFormatEU(String str) {
//* Date (Format: DD.MM.YYYY)*/
final String regexDateFormat = "^\\d{2}\\.\\d{2}\\.\\d{4}$";
if (str == null || !(Pattern.matches(regexDateFormat, str) ) ) {
return false;
}
String year = str.substring(6, 9);
//*Range from 1100 to current century*/
final String REGEX_31_DAY_MONTHS = "(0[1-9]|[12][0-9]|3[01])[\\.](0[13578]|1[02])[\\.](10|11|12|13|14|15|16|17|18|19|20)[0-9]{2}";
final String REGEX_30_DAY_MONTHS = "(0[1-9]|[12][0-9]|30)[\\.](0[469]|11)[\\.](10|11|12|13|14|15|16|17|18|19|20)[0-9]{2}";
final String REGEX_FEB_29_DAY_MONTHS = "29[\\.](02)[\\.](((10|11|12|13|14|15|16|17|18|19|20)(04|08|[2468][048]|[13579][26]))|2000)";
final String REGEX_FEB_1_28_DAY_MONTHS = "(0[1-9]|1[0-9]|2[0-8])[\\\\.](02)[\\\\.](10|11|12|13|14|15|16|17|18|19|20)[0-9]{2}";
final String REGEX_LEAP_YEAR = "((" REGEX_31_DAY_MONTHS ")|(" REGEX_30_DAY_MONTHS ")|("
REGEX_FEB_29_DAY_MONTHS ")|(" REGEX_FEB_1_28_DAY_MONTHS "))";
final String REGEX_NON_LEAP_YEAR = "((" REGEX_31_DAY_MONTHS ")|(" REGEX_30_DAY_MONTHS ")|("
REGEX_FEB_1_28_DAY_MONTHS "))";
final String CURRENT_REGEX = isLeapYear(year) ? REGEX_LEAP_YEAR
: REGEX_NON_LEAP_YEAR;
Pattern p = Pattern.compile(CURRENT_REGEX);
Matcher m = p.matcher(str);
return m.matches();
}
public static boolean isLeapYear(String str) {
boolean yearIsLeap = false;
int year = Integer.valueOf(str);
if ( ( ( year % 4 == 0 ) && ( year % 100 != 0 ) ) || ( year % 400 == 0 ) ) {
yearIsLeap = true;
}
return yearIsLeap;
}
}
The question are following: How this code can be optimized? Condition: regular expressions must be used.
CodePudding user response:
Rather than using pure regex and having to worry about edge cases like leap years, a better approach would be to just parse the input string using the specified format.
public static boolean checkDateFormatEU(String str) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy", Locale.ENGLISH);
try {
LocalDate.parse(str, formatter);
}
catch (DateTimeParseException e) {
System.out.println("Invalid date: " str);
return false;
}
return true;
}
If the input date cannot be parsed using your expected date format, then LocalDate#parse()
would throw an exception, which returns a false result. Otherwise, true would be returned.
CodePudding user response:
Condition: regular expressions must be used. - Well there's your problem!!
This is not a good use-case for regexes. They won't give you an efficient solution. They certainly won't give you a good1 solution.
But if you want to optimize this, consider precompiling the two regexes and saving the compiled versions in static
variables.
1 - OK, that is my opinion. But I suspect that the vast majority of experienced Java programmers would agree. Use the java.time.format
classes to do your validation. That's what they are designed for.