jsf - validate date with expression language

Go To StackoverFlow.com

3

I need to check the value of my birthdate input field. There should be several possibilities: dd.MM.yyyy, dd.M.yyyy, d.MM.yyyy, d.m.yyyy and also dd.MM.yy, dd.M.yy, d.MM.yy, d.m.yy. For example you can input 07.03.1993, 7.3.93 or whatever.

The following regex example just checks the format validation, but it doesn't check if the date exists (e.g. 29.02.2011 or 47.02.2011 will be allowed)

String s = (String) arg2;
        String pattern = "^(\\d{2}|\\d{1})\\.(\\d{2}|\\d{1})\\.(\\d{2}|\\d{4})$";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(s);

        if (m.matches()) {
            System.out.println(("date correct"));
        } else {
            System.out.println("date incorrect");
        }

edit: I just created the following regex statement, now it checks if the month is bigger than 12 and the day is bigger than 31. I think I should use regex first and then validate the date with SimpleDateFormat

String s = "^((0?[1-9]|[12][0-9]|3[01])\\.(0?[1-9]|1[012])\\.((19|20)\\d{2})$";
2012-04-04 07:42
by yves.beutler


2

If regex is not a must, you can try and convert your string to a date using the parse method of java.text.SimpleDateFormat and see if it succeeds.

If it does (you get a valid Date object), you have a valid date entered in your form (or input). If it does not succeed, the parse function returns null and the String you input was invalid.

Here's the javadoc for the parse method.

EDIT: For the extra validation in case you don't want to use setLenient, you can use the Date that you get from parse and convert it back to a String using the same format. Then just compare the String resulting from the conversion with the one you supply as input. If they match, you've got valid input.

2012-04-04 07:52
by lucian.pantelimon
the parse method will allow a 29.02 date for a non-leap yea - Simeon 2012-04-04 08:00
SimpleDateFormat.parse does no validation. E.g. if you do Date d = new SimpleDateFormat("yyyy-MM-dd").parse("2012-01-32");, then the Date d will refer to February 1:st, because the days "overflow" into the month - Alderath 2012-04-04 08:07
That's not true Alderath, use setLenient(false), then your date will give an exceptio - yves.beutler 2012-04-04 08:11
You can add some more validation by determining the leap years and checking for 29/02. But still, if the parse method allows for 29/02 in a non-leap year, what will the Date contain? I don't think the Date object returned will allow 29/02 in a non-leap year. You could try and use the static method java.sql.Date.valueOf and use java.sql.Date instead of java.util.Date - lucian.pantelimon 2012-04-04 08:13
Thanks @lucian.pantelimon, I'll combine your SimpleDateFormat with my regular expression. I'll show you if it work - yves.beutler 2012-04-04 08:14
@YvesBeutler Nice. I missed that. I was surprised when I notice that no exceptions were thrown. Imo, setLenient(false) should be default instead of the other way around. When calling parse, you expect to have errors reported - Alderath 2012-04-04 08:19
@Yves Beutler I've updated my answer so that you don't need to do a regex match for the extra validation - lucian.pantelimon 2012-04-04 08:23


0

You can split it to get day and month parts of the date.

Then you can do something like:

final int dayToCheck = 32; // user input
final int month = 2; // user input
final int year = 1981; // user input        

final Calendar cal = Calendar.getInstance();
cal.set(year, month, 1); // day doesn't need to be the user input, it can be any day in the month you want to check

if (cal.getActualMaximum(Calendar.DAY_OF_MONTH) > dayToCheck) {

    // the day is invalid
}
if (cal.getActualMinimum(Calendar.DAY_OF_MONTH) < dayToCheck) {

    // again, the day is invalid
}

You can do the same check with the Calendar.MONTH field.

I haven't checked if this compiles, but you should get the idea.

2012-04-04 08:00
by Simeon
There won't be an error if you write cal.set(2011,02,29). So I prefer @lucian.pantelimon's solution and combined it with my work - yves.beutler 2012-04-04 11:15
@YvesBeutler As I stated in the answer: You must not set the complete user input when you create the calendar. You need to set the year and the month only (you can always set 1 for the day). Then use cal.getActualMaximum(Calendar.DAY_OF_MONTH) to compare it to the user input for the day - Simeon 2012-04-04 11:27
Yes, that's true. But I think it's a better way to let the SimpleDateFormat check if the date is correct than a selfmade solution like yours - yves.beutler 2012-04-04 12:04
Ads