代码之家  ›  专栏  ›  技术社区  ›  Anand Shah

如何在Perl中检查有效的日期格式?

  •  1
  • Anand Shah  · 技术社区  · 17 年前


    我从数据库中的一个变量中得到一个日期字段,此时我正在使用以下代码检查日期是否为“yyyy-mm-dd”格式

    if ( $dat =~ /\d{3,}-\d\d-\d\d/ )
    

    我的问题是,有没有更好的方法来实现这一点。

    非常感谢

    7 回复  |  直到 14 年前
        1
  •  6
  •   wr.    17 年前

    这个 OWASP Validation Regex Repository 的美国格式日期版本,支持闰年:

    这个 Regular Expression Library

    ^\d{4}-\d{1,2}-\d{1,2}$
    
        2
  •  4
  •   szabgab Brandon Fosdick    12 年前

    但这样做的缺点是它会接受无效日期,比如2009-02-30。同样,如果您处理的日期成功地将其输入到数据库中的日期类型字段中,那么您应该是安全的。

    http://metacpan.org/pod/Date::Manip

        3
  •  3
  •   toolkit    17 年前

    怎么样

    /\d{2}\d{2}?-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/
    
        4
  •  2
  •   Anonymous    17 年前

    \d可以匹配其他语言的数字字符。YYY真的是一个有效的年份吗?如果必须是四位数,破折号,两位数,破折号,两位数,我更喜欢 /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/ /^[12][0-9]{3}-[0-9]{2}-[0-9]{2}$/ . 请注意要匹配的字符串周围的空格字符。

    当然,除了第二个示例中的第一个字符外,这不会检查存在的字符的合理性。如果需要,最好将其传递给日期解析模块,然后检查其输出的逻辑结果。

        5
  •  1
  •   Igor    17 年前

    你可以从以下几点开始:

    /\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|30|31)/ 
    
        6
  •  1
  •   Pradeep    9 年前

    最好的轻量级解决方案是使用 Date::Calc 子程序,下面是一个示例:

    use strict;
    use warnings
    use Date::Calc qw[check_date];
    
    ## string in YYYY-MM-DD format, you can have any format
    ## you like, just parse it
    my @dt_dob = unpack("A4xA2xA2",$str_dob_date);
    
    unless(check_date(@dt_dob)) {
        warn "Oops! invalid date!";
    }
    

    我希望这会有所帮助:-)

        7
  •  0
  •   Eric Roode Eric Roode    17 年前

    我强烈建议不要编写自己的正则表达式来实现这一点。日期/时间解析很简单,但有一些棘手的方面,这是一个已经解决了数百次的问题。无需再设计、编写和调试另一个解决方案。

    如果您只想解析特定的日期格式,那么最好使用Dave Rolsky优秀的DateTime模块的众多解析/格式化插件之一。

    如果要在匹配日期/时间值之后验证它们,我建议使用我的time::Normalize模块。

        8
  •  0
  •   Andy A.    5 年前

    我认为在没有外部检查的情况下使用正则表达式非常复杂!我用一个小潜艇来获得它:

    sub check_date {
        my $date_string = shift;
    
        # Check the string fromat and get year, month and day out of it.
        # Best to use a regex.
        return 0 unless $date_string =~ m/^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
        
        # 31. in a month with 30 days
        return 0 if ($3 >= 31 and ($2 == 4 or $2 == 6 or $2  == 9 or $2 == 11));
        # February 30. or 31.
        return 0 if ($3 >= 30 and $2 == 2);
        # February 29. in not a leap year.
        return 0 if ($2 == 2 and $3 == 29
                     and not ($1 % 4 == 0 and ($1 % 100 != 0 or $1 % 400 == 0)));
        
        # Date is valid
        return 1;
    }
    

    我的想法(以及大部分代码)来自 regular-expressions.info