【问题标题】:PHP Regex to check date is in YYYY-MM-DD format用于检查日期的 PHP 正则表达式为 YYYY-MM-DD 格式
【发布时间】:2012-11-02 11:27:47
【问题描述】:

我正在尝试检查最终用户输入的日期是否在 YYYY-MM-DD 中。正则表达式从来都不是我的强项,我设置的 preg_match() 总是得到错误的返回值。

所以我假设我把正则表达式弄得一团糟,详情如下。

$date="2012-09-12";

if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
    {
        return true;
    }else{
        return false;
    }

有什么想法吗?

【问题讨论】:

  • 正则表达式不足以验证日期。在正则表达式之后,您还应该使用以下两者之一:date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12"; 或 PHP 的 checkdate ( int $month , int $day , int $year )
  • 我现在不想验证它,我只是想确保它是 YYYY-MM-DD 格式。
  • 对于用户输入的值,除了在正则表达式之后,表单提交(以便您可以显示错误)之外,还有什么更好的“时间点”来验证?
  • 公平点,以后可以省点事。

标签: php regex date-format


【解决方案1】:

为此使用另一种机制可能会更好。

现代解决方案,DateTime:

$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());

这也验证了输入:$dt !== false 确保可以使用指定格式解析日期,array_sum 技巧是确保 PHP 不执行“月移”的一种简洁方式(例如,考虑到 1 月 32 日)是 2 月 1 日)。请参阅DateTime::getLastErrors() 了解更多信息。

带有explodecheckdate 的老式解决方案:

list($y, $m, $d) = array_pad(explode('-', $date, 3), 3, 0);
return ctype_digit("$y$m$d") && checkdate($m, $d, $y);

这也验证了输入也是有效日期。当然,您可以使用正则表达式来做到这一点,但这会更麻烦——而且 2 月 29 日根本无法使用正则表达式进行验证。

这种方法的缺点是您必须非常小心地拒绝所有可能的“错误”输入,同时在任何情况下都不会发出通知。方法如下:

  • explode 仅限于返回 3 个令牌(这样如果输入为“1-2-3-4”,$d 将变为“3-4”)
  • ctype_digit 用于确保输入不包含任何非数字字符(破折号除外)
  • 使用array_pad(使用默认值会导致checkdate 失败)确保返回足够多的元素,这样如果输入为“1-2”,list() 将不会发出通知

【讨论】:

  • +1,一直使用DateTime,从未听说过checkdate...真丢人。
  • @k102: DateTime 也可以这样做。我刚刚充实了答案,如果您愿意,请再看一遍。
  • 查看 PHP 手册,看起来第一个解决方案将验证不完整的日期(从当前日期填写缺失值)。
  • 解决方案 #1 的另一个问题:“不存在的值翻转”,例如2001-02-31 变为 2001-03-03。 (虽然 OP 没有明确要求这是不可能的。)
  • @user2428118:您是按照给定的方式尝试解决方案#1,还是只尝试第一行?您是否单击了我提供给getLastErrors 文档的链接?
【解决方案2】:

试试这个。

$date="2012-09-12";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
    return true;
} else {
    return false;
}

【讨论】:

  • return (bool)preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date);
  • 为什么这被标记为正确答案?这对于许多无效日期(如 2016-02-30 和 2016-09-31)返回 true
  • 这个问题是关于如何检查日期格式(YYYY-MM-DD),标记为接受的答案并不总是最好的答案,它只是意味着它对提问的人有效,阅读这个美丽的旅程:stackoverflow.com/tour .
  • @Graham 旧帖子我知道但同意 Stramin - 这个问题询问格式验证 - 不是实际日期验证
  • 验证日期时间 preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1 -2][0-9]|3[0-1])T(0[1-9]|1[0-9]|2[0-4]):(0[1-9]|1[ 0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|6[0-9])$/",$dateTime)
【解决方案3】:

yyyy-mm-dd: /^((((19|[2-9]\d)\d{2})\-(0[13578]|1[02])\-(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\-(0[13456789]|1[012])\-(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\-02\-(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\-02\-29))$/g

年年/月/日: /^((((19|[2-9]\d)\d{2})\/(0[13578]|1[02])\/(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\/(0[13456789]|1[012])\/(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\/02\/(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\/02\/29))$/g

mm-dd-yyyy: /^(((0[13578]|1[02])\-(0[1-9]|[12]\d|3[01])\-((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\-(0[1-9]|[12]\d|30)\-((19|[2-9]\d)\d{2}))|(02\-(0[1-9]|1\d|2[0-8])\-((19|[2-9]\d)\d{2}))|(02\-29\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

mm/dd/yyyy: /^(((0[13578]|1[02])\/(0[1-9]|[12]\d|3[01])\/((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\/(0[1-9]|[12]\d|30)\/((19|[2-9]\d)\d{2}))|(02\/(0[1-9]|1\d|2[0-8])\/((19|[2-9]\d)\d{2}))|(02\/29\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

dd/mm/yyyy: /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

dd-mm-yyyy: /^(((0[1-9]|[12]\d|3[01])\-(0[13578]|1[02])\-((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\-(0[13456789]|1[012])\-((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\-02\-((19|[2-9]\d)\d{2}))|(29\-02\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

【讨论】:

  • 以上所有内容都适用于从 1900 到 9999 的日期,这是大多数时候需要的,并且比我的尝试短 74 个字符(重新使用 yyyy-mm-dd 格式)。如果您想要 1900 年之前的日期,那么对 Shyju 答案的小调整将允许从 1000 年开始,并且再短 23 个字符:^((([1-9]\d{3})\-(0[13578]| 1[02])\-(0[1-9]|[12]\d|3[01]))|((((19|[2-9]\d)\d{2})\-( 0[13456789]|1[012])\-(0[1-9]|[12]\d|30))|(([1-9]\d{3})\-02\-(0 [1-9]|1\d|2[0-8]))|(([1-9]\d(0[48]|[2468][048]|[13579][26])|( (16|[2468][048]|[3579][26])00))\-02\-29))$
【解决方案4】:

我知道这是一个老问题。但我认为我有一个很好的解决方案。

$date = "2016-02-21";
$format = "Y-m-d";

if(date($format, strtotime($date)) == date($date)) {
    echo "true";
} else {
    echo "false";
}

你可以试试。如果您将日期更改为 21.02.2016,则回显是错误的。如果你之后将格式更改为 d.m.Y,则回显为 true。

使用这个简单的代码,您应该能够检查使用了哪种日期格式,而无需通过正则表达式进行检查。

也许有人会对每个案例进行测试。但我认为我的想法通常是有效的。对我来说这似乎是合乎逻辑的。

【讨论】:

  • 我认为你不需要 date() 在 if 行的 $date 附近。 if(date($format, strtotime($date)) == $date) - 应该足够了
  • 这似乎工作正常,它可以处理闰年
【解决方案5】:

你可以这样做:

if (preg_match("/\d{4}\-\d{2}-\d{2}/", $date)) {
    echo 'true';
} else {
    echo 'false';
}

但你最好用这个:

$date = DateTime::createFromFormat('Y-m-d', $date);
if ($date) {
    echo $date -> format('Y-m-d');
}

在这种情况下,您将获得一个比字符串更易于使用的对象。

【讨论】:

  • 这里使用的 dateTime 技术对于像 2016-05-44 这样不是实际日期的日期返回 true
  • 这不是一个很好的例子,特别是如果你想获取日期(Y-m-d)。示例:0175-44-19927 将通过。
  • 我没有看到 ^$
【解决方案6】:

可能对某人有用:

$patterns = array(
            'Y'           =>'/^[0-9]{4}$/',
            'Y-m'         =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])$/',
            'Y-m-d'       =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$/',
            'Y-m-d H'     =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4])$/',
            'Y-m-d H:i'   =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?(0|[0-5][0-9]|60)$/',
            'Y-m-d H:i:s' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?((0|[0-5][0-9]):?(0|[0-5][0-9])|6000|60:00)$/',
        );
echo preg_match($patterns['Y'], '1996'); // true
echo preg_match($patterns['Y'], '19966'); // false
echo preg_match($patterns['Y'], '199z'); // false
echo preg_match($patterns['Y-m'], '1996-0'); // false
echo preg_match($patterns['Y-m'], '1996-09'); // true
echo preg_match($patterns['Y-m'], '1996-1'); // true
echo preg_match($patterns['Y-m'], '1996/1'); // true
echo preg_match($patterns['Y-m'], '1996/12'); // true
echo preg_match($patterns['Y-m'], '1996/13'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-1'); // true
echo preg_match($patterns['Y-m-d'], '1996-11-0'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-32'); // false
echo preg_match($patterns['Y-m-d H'], '1996-11-31 0'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 00'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 24'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 25'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 2400'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:00'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:59'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:60'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:6000'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:00'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:59'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:60'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:01'); // false

【讨论】:

【解决方案7】:

我正在搜索“如何验证日期”并找到了这个解决方案,它很旧,但我将分享以下可用于在 php 中验证日期的方法,

checkdate('01', '31', '2019')

【讨论】:

    【解决方案8】:

    验证通用日期格式的功能:

    function validateDate($date, $format = 'Y-m-d') {
      $d = DateTime::createFromFormat($format, $date);
      return $d && $d->format($format) == $date;
    }
    

    执行示例:

    var_dump(validateDate('2021-02-28')); // true
    var_dump(validateDate('2021-02-29')); // false
    

    【讨论】:

    • 请始终将您的答案放在上下文中,而不仅仅是粘贴代码。有关详细信息,请参阅here。还请编辑您的答案以包含降价块中的所有代码部分
    【解决方案9】:

    以下确保数字 YYYY(1900-2099)-MM(01-12)-DD(01-31) 以及使用 checkdate() 函数来确保日期正确性,例如2月29日:

    $date_pattern = '/^(19|20)\d{2}\-(0[1-9]|1[0-2])\-(0[1-9]|[12][0-9]|3[01])$/';
    
    if (empty($date) || (!preg_match("$date_pattern", $date, $m) || (!checkdate($m[2], $m[3], $m[1])))) {
        $echo 'Invalid Start date e.g. YYYY-MM-DD';
    }
    

    要更改日期模式和年份范围:

    // 模式 DD/MM/YYYY 其中 DD (01-31)、MM (01-12) 和 YYYY (1950-2099) & 必须是数字 - 将 checkdate () 替换为 !checkdate($m[2], $m[1], $m[3]

    // 扩展年份范围,例如1900-2099 /^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/(19|20)\ d{2}$/ - 将 checkdate () 替换为 !checkdate($m[2], $m[1], $m[3]

    【讨论】:

      【解决方案10】:

      标准:

      能被 4 整除的每一年都是闰年,除非它能被 100 整除,除非它能被 400 整除。所以:

      2004 - leap year - divisible by 4
      1900 - not a leap year - divisible by 4, but also divisible by 100
      2000 - leap year - divisible by 4, also divisible by 100, but divisible by 400
      

      二月闰年有 29 天,非闰年有 28 天

      4 月、6 月、9 月和 11 月 30 天

      一月、三月、五月、七月、八月、十月和十二月共 31 天

      测试:

      以下日期均应通过验证:

      1976-02-29
      2000-02-29
      2004-02-29
      1999-01-31
      

      以下日期均应未通过验证:

      2015-02-29
      2015-04-31
      1900-02-29
      1999-01-32
      2015-02-00
      

      范围:

      我们将测试从 1000 年 1 月 1 日到 2999 年 12 月 31 日的日期。从技术上讲,目前使用的公历仅在 1753 年用于大英帝国,并在 1600 年代的不同年份用于欧洲国家,但是我不会担心这个。

      正则表达式测试闰年:

      能被 400 整除的年份:

      1200|1600|2000|2400|2800
      can be shortened to:
      (1[26]|2[048])00
      
      if you wanted all years from 1AD to 9999 then this would do it:
      (0[48]|[13579][26]|[2468][048])00
      if you're happy with accepting 0000 as a valid year then it can be shortened:
      ([13579][26]|[02468][048])00
      

      能被 4 整除的年份:

      [12]\d([02468][048]|[13579][26])
      

      能被 100 整除的年份:

      [12]\d00
      

      不能被 100 整除:

      [12]\d([1-9]\d|\d[1-9])
      

      能被 100 整除但不能被 400 整除的年份:

      ((1[1345789])|(2[1235679]))00
      

      能被 4 整除,但不能被 100 整除:

      [12]\d([2468][048]|[13579][26]|0[48])
      

      闰年:

      divisible by 400 or (divisible by 4 and not divisible by 100)
      ((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48])
      

      不能被 4 整除:

      [12]\d([02468][1235679]|[13579][01345789])
      

      不是闰年:

      Not divisible by 4 OR is divisible by 100 but not by 400
      ([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)
      

      有效月份和日期不包括二月(MM-DD):

      ((01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|((04|06|09|11)-(0[1-9]|[12]\d|30))
      shortened to:
      ((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30))
      

      2 月 28 天:

      02-(0[1-9]|1\d|2[0-8])
      

      二月有 29 天:

      02-(0[1-9]|[12]\d)
      

      有效日期:

      (leap year followed by (valid month-day-excluding-february OR 29-day-february)) 
      OR
      (non leap year followed by (valid month-day-excluding-february OR 28-day-february))
      
      ((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8]))))
      

      所以你有一个 1000 年 1 月 1 日到 2999 年 12 月 31 日之间日期的正则表达式,格式为 YYYY-MM-DD。

      我怀疑它可以缩短很多,但我会留给其他人。

      这将匹配所有有效日期。如果您希望它仅在仅包含一个日期而不包含其他任何内容时才有效,则将其包装在 ^( )$ 中,如下所示:

      ^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$
      

      如果您希望它作为可选的日期条目(即它可以是空白或有效日期),则在开头添加 ^$|,如下所示:

      ^$|^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$
      

      【讨论】:

      • 那是英雄式的表达,解释的很好。
      • 您是否有强有力的证据证明它会通过每个有效案例并在每个无效案例上失败?
      • @Md Ashraful Islam No
      • @Graham 没问题,我们在我们的网站上使用它。我希望不会出现问题。
      • @Md Ashraful Islam - 我们也在使用它,到目前为止还没有遇到任何问题
      【解决方案11】:

      preg_match 需要一个 / 或另一个字符作为分隔符。

      preg_match("/^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$/",$date)
      

      你还应该检查那个日期的有效性,这样你就不会得到像 9999-19-38 这样的结果

      bool checkdate ( int $month , int $day , int $year )
      

      【讨论】:

        【解决方案12】:

        您可以将 preg_match 与 checkdate php 函数一起使用

        $date  = "2012-10-05";
        $split = array();
        if (preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $split))
        {
            return checkdate($split[2], $split[3], $split[1]);
        }
        
        return false;
        

        【讨论】:

        • return preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $split)) && checkdate($split[2],$split[3],$split[1]) ;
        【解决方案13】:

        如果您想匹配该类型的日期,请使用:

        preg_match("~^\d{4}-\d{2}-\d{2}$~", $date)
        

        【讨论】:

          【解决方案14】:

          这应该告诉您格式是否有效以及输入日期是否有效。

              $datein = '2012-11-0';
          
              if(preg_match('/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/', $datein)){
                  echo 'good';
              }else{
                  echo 'no good';
              }
          

          【讨论】:

            【解决方案15】:

            这完全取决于你希望这个函数有多严格。例如,如果您不想允许超过 12 个月和超过 31 天(不取决于月份,这需要编写日期逻辑),它可能会变得非常复杂:

            function checkDate($date)
            {
              $regex = '/^' . 
                '(' .
            
                // Allows years 0000-9999
                '(?:[0-9]{4})' .
                '\-' .
            
                // Allows 01-12
                '(?:' .
                '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
                '(?:11)|(?:12)' .
                ')' .
                '\-' .
            
                // Allows 01-31
                '(?:' .
                '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
                '(?:11)|(?:12)|(?:13)|(?:14)|(?:15)|(?:16)|(?:17)|(?:18)|(?:19)|(?:20)|' .
                '(?:21)|(?:22)|(?:23)|(?:24)|(?:25)|(?:26)|(?:27)|(?:28)|(?:29)|(?:30)|' .
                '(?:31)' .
                ')' .
            
                '$/';
            
              if ( preg_match($regex, $date) ) {
                return true;
              }
            
              return false;
            }
            
            $result = checkDate('2012-09-12');
            

            我个人会选择:/^([0-9]{4}\-([0-9]{2}\-[0-9]{2})$/

            【讨论】:

            • 这个正则表达式过于复杂。 0[1-9]|1[0-2] 匹配 01-12 月,0[1-9]|[12][0-9]|3[01] 匹配 01-31 天。
            • 对不起,我呕吐了
            【解决方案16】:

            要在 php 中使用日期,您应该遵循 php 标准,这样给定的正则表达式将确保您拥有可以使用 PHP 操作的有效日期。

                preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)
            

            【讨论】:

            • 你的 rgex 错误,它不会匹配 1980-01-01 但会匹配 2100-02-29
            【解决方案17】:

            格式 1 : $format1 = "2012-12-31";

            格式 2 : $format2 = "31-12-2012";

            if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$format1)) {
                return true;
            } else {
                return false;
            }
            
            if (preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-[0-9]{4}$/",$format2)) {
                return true;
            } else {
                return false;
            }
            

            【讨论】:

              【解决方案18】:

              你也可以这样做:

              if (DateTime::createFromFormat('Y-m-d', $date)->format('Y-m-d') === $date) {
              
                  // date is correctly formatted and valid, execute some code
              
              }
              

              这不仅会检查格式,还会检查日期自身的有效性,因为DateTime 将只创建有效日期并且这需要匹配输入。

              【讨论】:

                【解决方案19】:

                你可以使用

                function validateDate($date, $format = 'Y-m-d H:i:s')
                {
                    $d = DateTime::createFromFormat($format, $date);
                    return $d && $d->format($format) == $date;
                }
                
                $date="2012-09-12";    
                echo validateDate($date, 'Y-m-d'); // true or false
                

                【讨论】:

                  【解决方案20】:

                  来自 Laravel 5.7 和日期格式,即:12/31/2019

                  function checkDateFormat(string $date): bool
                  {
                      return preg_match("/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/[0-9]{4}$/", $date);
                  }
                  

                  【讨论】:

                    【解决方案21】:

                    在一行语句中检查并验证YYYY-MM-DD 日期

                    function isValidDate($date) {
                        return preg_match("/^(\d{4})-(\d{1,2})-(\d{1,2})$/", $date, $m)
                            ? checkdate(intval($m[2]), intval($m[3]), intval($m[1]))
                            : false;
                    }
                    

                    输出将是:

                    var_dump(isValidDate("2018-01-01")); // bool(true)
                    var_dump(isValidDate("2018-1-1"));   // bool(true)
                    var_dump(isValidDate("2018-02-28")); // bool(true)
                    var_dump(isValidDate("2018-02-30")); // bool(false)
                    

                    允许不带前导零的日期和月份。如果您不想允许这样做,则正则表达式应该是:

                    "/^(\d{4})-(\d{2})-(\d{2})$/"
                    

                    【讨论】:

                      【解决方案22】:

                      如果有任何帮助,这里是 j-n-Y 格式的正则表达式(年份必须大于 2018):

                      if (preg_match('/^([1-9]|[1-2][0-9]|[3][0-1])\-([1-9]|[1][0-2])\-(?:20)([1][8-9]|[2-9][0-9])$/', $date)) {
                         // Do stuff
                      }
                      

                      【讨论】:

                        【解决方案23】:

                        此方法可用于在 PHP 中验证日期。当前方法适用于 mm/dd/yyyy 格式。您必须根据explode 中的格式和分隔符更新checkdate 中的参数序列。

                            function isValidDate($dt)
                            {
                                $dtArr = explode('/', $dt);
                                if (!empty($dtArr[0]) && !empty($dtArr[1]) && !empty($dtArr[2])) {
                                    return checkdate((int) $dtArr[0], (int) $dtArr[1], (int) $dtArr[2]);
                                } else {
                                    return false;
                                }
                            }
                        

                        【讨论】:

                          【解决方案24】:

                          [如果你使用 Symfony 4.1.2 试试这个][1]

                            $validDate = explode("-",$request->get('date'));
                                  if (checkdate(filter_var($validDate[1],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[0],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[2],FILTER_SANITIZE_NUMBER_INT))){
                                      $date = date_create(filter_var($request->get('date'),FILTER_SANITIZE_SPECIAL_CHARS));
                                  }else{
                                      return $this->redirectToRoute('YOUR_ROUTE');
                                  }
                          

                          【讨论】:

                            【解决方案25】:

                            更实用的模式可能是这样的

                            $date="2012-09-12";
                            
                            if (preg_match("/^(20[0-9]{2})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
                                return true;
                            } else {
                                return false;
                            }
                            

                            这将阻止放置 9999-09-12 这样的值。

                            【讨论】:

                              猜你喜欢
                              • 2023-04-07
                              • 2017-07-10
                              • 1970-01-01
                              • 1970-01-01
                              • 2012-01-03
                              • 2022-01-04
                              • 2013-11-15
                              • 1970-01-01
                              相关资源
                              最近更新 更多