如何验证日期而不是日期和月份的前导零?

时间:2017-06-14 15:42:59

标签: php validation date date-formatting leading-zero

我需要在php中验证精确的日期格式。

在我的情况下,最佳日期格式应为:例如function displayGame() { if (!$this->isOver()) { echo "<div id=\"board\">"; $i=1; for ($x = 0; $x < 3; $x++) { for ($y = 0; $y < 3; $y++) { require('config.inc.php'); $db = new PDO("mysql:dbname=$db_name;host=$db_host", $db_user, $db_pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); echo "<div id=\"$i\" class=\"board_cell\">"; $i++; $query = $db->prepare('SELECT * FROM tictactoe WHERE value IS NOT NULL and id = ?'); if ($this->board[$x][$y]) $query->execute([$lookup[$key]]); echo "<p>\"{$this->board[$x][$y]}\"</p>"; else { echo "<select name=\"{$x}_{$y}\"> <option value=\"\"></option> <option value=\"{$this->player}\">{$this->player}</option> </select>"; } echo "</div>"; } echo "<div class=\"break\"></div>"; } echo " <p align=\"center\"> <input type=\"submit\" name=\"move\" value=\"Take Turn\" /><br/> <b>It's player {$this->player}'s turn.</b></p> </div>"; } else { if ($this->isOver() != "Tie") echo successMsg("Congratulations player " . $this->isOver() . ", you've won the game!"); else if ($this->isOver() == "Tie") echo errorMsg("Whoops! Looks like you've had a tie game. Want to try again?"); session_destroy(); echo "<p align=\"center\"><input type=\"submit\" name=\"newgame\" value=\"New Game\" /></p>"; } } function move($postdata) { if ($this->isOver()) return; require('config.inc.php'); $db = new PDO("mysql:dbname=$db_name;host=$db_host", $db_user, $db_pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); $postdata = array_unique($postdata); $lookup = ['0_0'=>1, '0_1'=>2, '0_2'=>3, '1_0'=>4, '1_1'=>5, '1_2'=>6, '2_0'=>7, '2_1'=>8, '2_2'=>9]; $query = $db->prepare('UPDATE tictactoe SET tictac = ? WHERE id = ?'); foreach ($postdata as $key => $value) { if ($value!=$this->player) continue; $query->execute([$this->player, $lookup[$key]]); if ($value == $this->player) { $coords = explode("_", $key); $this->board[$coords[0]][$coords[1]] = $this->player; if ($this->player == "X") $this->player = "O"; else $this->player = "X"; $this->totalMoves++; } } if ($this->isOver()) return; } (没有前导零),代码应该允许我避免使用其余的日期格式。

以下代码是我写的但没有结果:

1/1/2017

问题是代码没有正确验证日期;它接受各种日期格式。

4 个答案:

答案 0 :(得分:2)

您的日期分隔符为null而不是/,因此-\/的正则表达式添加/。并在正则表达式的开头使用^

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

答案 1 :(得分:2)

我注意到OP提交的答案不是防弹的,所以我开始研究问题评论中提到的一些功能以及我自己的一些想法。

我同意apokryfos,因为使用正则表达式验证日期表达式不是最佳做法。纯正的正则表达式解决方案将成为一种越来越冗长且逐渐被理解的模式,因为它必须在过去和未来都考虑闰年。出于这个原因,我已经调查了php提供的一些日期函数。

    Alex Howansky建议
  1. date_parse_from_format()。不幸的是,对于这种情况,它不会是一个独立的解决方案,因为format参数遵循DateTime::createFromFormat()的语法/规则:
  2. enter image description here

    了解dj的组合方式,mn。因此,此函数将捕获无效日期,但不会捕获不需要的前导零。

      根据Casimir et Hippolyte的建议,
    1. strptime()。此函数使用%e提供不带前导零的匹配日期。此函数没有匹配非零前导月份数字的字符。此外,此功能可能会因操作系统而出现打嗝。

    2. check_date()似乎是一个合乎逻辑的选择,但同样不会因为零导数而退缩。此外,此功能需要比其他功能更多的数据准备,因为它需要个性化月,日和年值。

    3. deceze建议的关于a slightly different scenario
    4. if(!DateTime::createFromFormat('j/n/Y', $date))在这种情况下不起作用。 createFromFormat()将竭尽全力构建一个有效的日期 - 即使像99/99/9999这样的字符串也能完成。

    5. 为了创建最简洁的表达式,我可以使用DateTime类作为看似无懈可击的解决方案:

      if (($d=DateTime::createFromFormat('n/j/Y',$date)) && $date==$d->format('n/j/Y')){
          // valid
      }else{
          // invalid
      }
      
        在这种情况下,

      strtotime()可以与单个条件一起使用,因为OP的日期格式使用斜杠作为分隔符,此函数将正确解析日期表达式“American-style”。

           

      这似乎是检查没有前导零的有效日期的最简单方法:Demo Link

      if(date('n/j/Y',strtotime($date))==$date){
          // valid
      }else{
          // invalid
      }
      

      如果您正在处理日期时间表达式并且不希望检查时间部分,则可以在条件行之前调用此行:

      $date = explode(' ', $date)[0];  // create an array of two elements: date and time, then only access date
      

      Demo Link

      $date = strstr($date, ' ', true); // extract substring prior to first space
      

答案 2 :(得分:1)

您可以与Carbon一起使用

$date->format('j')

答案 3 :(得分:0)

几个小时后,我终于找到了正确的答案。 php的正确模式是使用单引号(')而不是双引号(“)例如:

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

这对我来说很好...感谢大家特别对@Mohammad Hamedani来说因为表达是正确的,但是f ******引用让我发疯了