[英]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在后端运行,看起来你有一个前端问题。
我也怀疑问题是你使用的输入类型。 如果一个浏览器不支持您指定的输入类型,则默认为文本。 在这里看到:
我的浏览器不知道<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])$
它将验证年份从19
或20
开始,月份不大于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-30
, DateTime
对象包含2018-03-02
。 我认为这是因为2018年2月有28天,即最大日期是2018-02-28
,当我们通过一天30
,createFromFormat只是增加了30天,在2018-02-01
,没有任何前日期创建新的日期验证。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.