繁体   English   中英

正则表达式使用格式为YYYY-MM-DD在PHP中验证日期

[英]Regex to validate date in PHP using format as YYYY-MM-DD

我正在尝试制作日期正则表达式验证器。 我遇到的问题是我使用的是带有"date"类型的输入字段,它就像Chrome中的魅力一样; 它在Chrome中打开了一个日历,但在其余部分它什么也没做,所以我决定手动输入其余的日期。

这是我的错误抛出消息(我正在寻找YYYY-MM-DD格式):

$date_regex ='#^(19|20)\d\d[\- /.](0[1-9]|1[012])[\- /.](0[1-9]|[12][0-9]|3[01])$#';
$hiredate = $_POST['hiredate'];
if (!preg_match($date_regex, $hiredate)){
    $errors[] = 'Your hire date entry does not match the YYYY-MM-DD required format.';
}

我知道有很多关于这方面的例子,但我已经尝试了20个,我无法解决它。 也许我错过了什么。

这是输入字段,如果有些相关:

<input type="date" name="hiredate" />

不要使用正则表达式,您可以使用DateTime::createFromFormat获得相同的结果

// specify your date's original format, in this example m/d/Y (e.g. 08/31/2013)
$format = "m/d/Y";
$hireDate = DateTime::createFromFormat($format, $_POST['hiredate']);
if(!$hireDate) {
 // createFromFormat returns false if the format is invalid;
} else {
   //change it to any format you want with format() (e.g. 2013-08-31)
   echo $hireDate->format("Y-m-d");
}

你可以在这里阅读更多:

http://php.net/manual/en/datetime.createfromformat.php

但是,似乎这个问题与PHP完全无关。

PHP在后端运行,看起来你有一个前端问题。

我也怀疑问题是你使用的输入类型。 如果一个浏览器不支持您指定的输入类型,则默认为文本。 在这里看到:

http://jsfiddle.net/FKGCA/

我的浏览器不知道<input type="whatever" /><input type="whatever" /> ,因此它将输入类型默认为“text”。 如果我将这4个输入包装在<form action="myForm.php" method="POST"></form>标记中,浏览器会将输入发送到服务器,因为服务器不关心/知道输入是否是隐藏,单选按钮,选择,文本或密码。 服务器只接收原始数据。

更有可能的是,您的问题在于您的Javascript,而不是您的PHP。 尝试查看未显示小部件的浏览器是否告诉您页面中存在某种错误。

Safari和Firefox都有开发/调试工具,对IE不太确定。

你的正则表达式没有用,因为你有未转义 /分隔符。

将以YYYY-MM-DD格式验证日期的正则表达式如下:

^(19|20)\d\d[\-\/.](0[1-9]|1[012])[\-\/.](0[1-9]|[12][0-9]|3[01])$

它将验证年份从1920开始,月份不大于12且不等于0且日期不大于31且不等于0

在线示例

使用您的初始示例,您可以像这样测试它:

$date_regex = '/^(19|20)\d\d[\-\/.](0[1-9]|1[012])[\-\/.](0[1-9]|[12][0-9]|3[01])$/';
$hiredate = '2013-14-04';

if (!preg_match($date_regex, $hiredate)) {
    echo '<br>Your hire date entry does not match the YYYY-MM-DD required format.<br>';
} else {
    echo '<br>Your date is set correctly<br>';      
}

在线示例

在一行声明中检查并验证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;
}

请参阅我的答案的细节在这里

不要盲目使用DateTime::createFromFormat来验证日期。 让我们看2018-02-30不存在的日期,看看:

$d = DateTime::createFromFormat("Y-m-d", "2018-02-30");
var_dump((bool) $d); // bool(true)

是的,它会返回true ,而不是您所预期的false 更有趣的:

$d = DateTime::createFromFormat("Y-m-d", "2018-99-99");
var_dump((bool) $d); // bool(true)

也是true ......所以,它只验证了位数。 再试一次:

$d = DateTime::createFromFormat("Y-m-d", "ABCD-99-99");
var_dump($d); // bool(false)

最后是false

我们可以从这个片段看到这里发生了什么:

$d = DateTime::createFromFormat("Y-m-d", "2018-02-30");
var_dump($d);

// var_dump OUTPUT
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2018-03-02 16:41:34.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(3) "UTC"
}

正如您所看到的,当我们传递不存在的2018-02-30DateTime对象包含2018-03-02 我认为这是因为2018年2月有28天,即最大日期是2018-02-28 ,当我们通过一天30 ,createFromFormat只是增加了30天,在2018-02-01 ,没有任何前日期创建新的日期验证。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM