在PHP中验证日期格式

15

我正在尝试使用PHP验证日期。

我希望以下日期格式是有效的:

d/m/yy
d/m/yyyy
dd/m/yy
dd/m/yyyy
d/mm/yy
d/mm/yyyy
dd/mm/yy
dd/mm/yyyy

我尝试了许多常规表达式和不同变体的checkdate()函数。目前我有这样的代码:

function _date_is_valid($str)
{
     if(strlen($str) == 0)
         return TRUE;
     if(substr_count($str,'/') == 2)
     {
         if (preg_match("/^((((31\/(0?[13578]|1[02]))|((29|30)\/(0?[1,3-9]|1[0-2])))\/(1[6-9]|[2-9]\d)?\d{2})|(29\/0?2\/(((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))|(0?[1-9]|1\d|2[0-8])\/((0?[1-9])|(1[0-2]))\/((1[6-9]|[2-9]\d)?\d{2}))/", $str))
         {
             $datearray = explode('/',$str);
             if($datearray[2] > 2030)
                 return FALSE;
             return checkdate($datearray[1], $datearray[0], $datearray[2]);
         } 
         else 
         {
             return FALSE;
         }
     }
     return FALSE;
}

然而,这种方法可以验证如11/11/200和11/11/200#之类的日期。

我该如何验证日期以匹配所需格式?

编辑:我可以检查datearray [2]是否在2010到2030年之间且在10到30之间。但是有没有一种使用正则表达式来检查它的方法?

编辑1:当strlen($str) == 0时返回TRUE的原因是我希望用户能够添加事件,而不知道事件发生的时间,以便其他人可以确定时间表并将事件分配给特定日期。


仅供记录。最终我做了:

function _date_is_valid($str)
{
    if(strlen($str) == 0) //To accept entries without a date
        return TRUE;
    if(substr_count($str,'/') == 2)
    {
        list($d,$m,$y) = explode('/',$str);
        if(($y >= 10 && $y <= 30) || ($y >= 2010 && $y <= 2030))
        {
            return checkdate($m,$d,$y);
        }
    }
    return FALSE;
}

感谢您所有的回答

7个回答

24
function _date_is_valid($str) {
    if (substr_count($str, '/') == 2) {
        list($d, $m, $y) = explode('/', $str);
        return checkdate($m, $d, sprintf('%04u', $y));
    }

    return false;
}

应该使用checkdate(),而不是check_date()。除此之外,看起来很不错。+1 - Decent Dabbler
如果您不检查“/”的计数,它将在无效字符串上抛出PHP通知或警告。 - antpaw
我稍微修改了一下,以便在特定年份之后不验证日期,因为php checkdate()验证类似于20111的年份,而在这种情况下,这不是我想要的。 - LukeP
2
如果没有两个分隔符“/”怎么办? - Gumbo

8
如果日期格式始终为年/月/日,您可以使用checkdate函数:
function _date_is_valid($str)
{
    $array = explode('/', $str);

    $day = $array[0];
    $month = $array[1];
    $year = $array[2];

    $isDateValid = checkdate($month, $day, $year);
    return $isDateValid;
}

应该使用checkdate()而不是check_date()。你可能想要对$array索引执行isset()检查。除此之外,看起来很不错。+1 - Decent Dabbler
哦,是的,你说得对,它是checkdate(),从问题中复制而来,没有检查它。谢谢。 - ahmetunal
如果没有两个分隔符“/”怎么办? - Gumbo

3
一种简单的方法是这样做。
<?php
    if(!$formated_date = date_create_from_format('Y-m-d',$dateVar))

2

试试这个:

function _date_is_valid($str) {
    if (strlen($str) == 0) {
        return TRUE;
    }
    return preg_match('/^(\d{1,2})\/(\d{1,2})\/((?:\d{2}){1,2})$/', $str, $match) && checkdate($match[2], $match[1], $match[3]) && $match[2] <= 2030;
}

我想允许日期留空或以有效格式输入。这是一种事件日历,您可以为某个日期预订事件,也可以预订事件,然后由其他人稍后分配日期。 - LukeP
不检查日期或月份是否有效。 - Douglas Leeder
@Douglas Leeder: checkdate 函数用于检查日期是否合法。 - Gumbo
抱歉 - 没有注意到水平滚动条。而 preg_match 适合于显示宽度。 - Douglas Leeder

1

我用简单的方法验证了它

    function dateValidate($pDate) {
    if(empty($pDate)) 
        return true; 
    $chDate = date('Y-m-d', strtotime($pDate));
    if($chDate != '1970-01-01')
        return true;
    else 
        return false;
}

你也可以使用正则表达式来找到它


1

我刚刚修改了上面的马丁答案,它将验证任何类型的日期并以您喜欢的格式返回。

通过编辑脚本下面的这行strftime("10-10-2012", strtotime($dt));来改变格式。

<?php

        echo is_date("13/04/10");

        function is_date( $str )
        {
        $flag = strpos($str, '/');

        if(intval($flag)<=0){
          $stamp = strtotime( $str );
         }else {
          list($d, $m, $y) = explode('/', $str);      
          $stamp = strtotime("$d-$m-$y");
         } 
          //var_dump($stamp) ;

          if (!is_numeric($stamp))
          {
             //echo "ho" ;
             return "not a date" ;       
          }

          $month = date( 'n', $stamp ); // use n to get date in correct format
          $day   = date( 'd', $stamp );
          $year  = date( 'Y', $stamp );

          if (checkdate($month, $day, $year))
          {
             $dt = "$year-$month-$day" ;
             return strftime("%d-%b-%Y", strtotime($dt));
             //return TRUE;
          }else {
          return "not a date" ;
          }
         }

    ?>

0

如果(strtotime($str) !== FALSE),那么$valid = TRUE;怎么样?


1
-1:OP非常明确要求接受哪些格式。您的解决方案允许更多的格式。 - Decent Dabbler
1
还有一个问题是dd/mm/yyyy和mm/dd/yyyy之间的区别。 - LukeP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接