【问题标题】:jsf - validate date with expression languagejsf - 使用表达式语言验证日期
【发布时间】:2012-04-17 21:51:31
【问题描述】:

我需要检查我的生日输入字段的值。应该有几种可能性:dd.MM.yyyydd.M.yyyyd.MM.yyyyd.m.yyyy 以及dd.MM.yydd.M.yyd.MM.yyd.m.yy。例如,您可以输入 07.03.1993、7.3.93 或其他任何内容。

以下正则表达式示例仅检查格式验证,但不检查日期是否存在(例如 29.02.2011 或 47.02.2011 将被允许)

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");
        }

编辑:我刚刚创建了以下正则表达式语句,现在它检查月份是否大于 12 并且日期是否大于 31。我想我应该先使用正则表达式,然后使用 SimpleDateFormat 验证日期

String s = "^((0?[1-9]|[12][0-9]|3[01])\\.(0?[1-9]|1[012])\\.((19|20)\\d{2})$";

【问题讨论】:

    标签: java regex validation


    【解决方案1】:

    如果不需要正则表达式,您可以尝试使用java.text.SimpleDateFormatparse 方法将字符串转换为日期,看看是否成功。

    如果是这样(您得到一个有效的Date 对象),那么您在表单(或输入)中输入了一个有效的日期。如果不成功,parse函数返回null,你输入的String无效。

    Hereparse 方法的 javadoc。

    编辑:如果您不想使用setLenient,为了进行额外验证,您可以使用从parse 获得的Date,并使用相同的格式将其转换回String。然后只需将转换产生的String 与您作为输入提供的比较。如果它们匹配,则您的输入有效。

    【讨论】:

    • 解析方法将允许非闰年的 29.02 日期
    • SimpleDateFormat.parse 不进行验证。例如。如果您执行Date d = new SimpleDateFormat("yyyy-MM-dd").parse("2012-01-32");,则日期 d 将指代 2 月 1 日:st,因为日期“溢出”到月份。
    • 这不是真正的 Alderath,使用setLenient(false),那么你的日期将给出一个例外
    • 您可以通过确定闰年并检查 29/02 来添加更多验证。但是,如果 parse 方法允许在非闰年 29/02Date 将包含什么?我认为返回的 Date 对象不会允许 29/02 在非闰年。您可以尝试使用静态方法java.sql.Date.valueOf 并使用java.sql.Date 而不是java.util.Date
    • 感谢@lucian.pantelimon,我会将您的SimpleDateFormat 与我的正则表达式结合起来。我会告诉你它是否有效
    【解决方案2】:

    您可以将其拆分以获取日期的日和月部分。

    然后你可以这样做:

    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
    }
    

    您可以对 Calendar.MONTH 字段进行相同的检查。

    我没有检查这是否编译,但你应该明白了。

    【讨论】:

    • cal.set(2011,02,29)不会报错。所以我更喜欢@lucian.pantelimon 的解决方案,并将其与我的工作结合起来。
    • @YvesBeutler 正如我在回答中所说:创建日历时不得设置完整的用户输入。您只需要设置年份和月份(您始终可以将日期设置为 1)。然后使用cal.getActualMaximum(Calendar.DAY_OF_MONTH) 将其与当天的用户输入进行比较。
    • 是的,没错。但我认为让SimpleDateFormat 检查日期是否正确比像你这样的自制解决方案更好。
    猜你喜欢
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 2011-06-24
    • 2015-02-03
    • 1970-01-01
    • 2016-09-21
    • 1970-01-01
    相关资源
    最近更新 更多