正则表达式使用格式为 YYYY-MM-DD 在 PHP 中验证日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19773418/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Regex to validate date in PHP using format as YYYY-MM-DD
提问by Cataneo
I am trying to make a date regex validator. The issue I'm having is that I'm using an input field with "date"
type, which works like a charm in Chrome; it opens a calendar-like in Chrome, but in the rest it does nothing, so I decided to go for a manual input of the date for the rest.
我正在尝试制作一个日期正则表达式验证器。我遇到的问题是我使用了一个带"date"
类型的输入字段,它在 Chrome 中就像一个魅力;它在 Chrome 中打开一个类似日历的日历,但在其余部分它什么也不做,所以我决定手动输入其余部分的日期。
This is my error throwing message (I'm looking for YYYY-MM-DD format):
这是我的错误抛出消息(我正在寻找 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.';
}
I know there are a lot of examples about this, but I tried like 20 already and I couldn't solve it. Maybe I'm missing something.
我知道有很多关于这个的例子,但我已经尝试了 20 次,但我无法解决它。也许我错过了一些东西。
Here's the input field, if somewhat relevant:
这是输入字段,如果有些相关的话:
<input type="date" name="hiredate" />
回答by ILikeTacos
Do not use regex for this, you can get the same result by using DateTime::createFromFormat
不要为此使用正则表达式,您可以通过使用获得相同的结果 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");
}
you can read more here:
你可以在这里阅读更多:
http://php.net/manual/en/datetime.createfromformat.php
http://php.net/manual/en/datetime.createfromformat.php
However, it seems like the issue is totally unrelated to PHP.
但是,这个问题似乎与 PHP 完全无关。
PHP runs on the back end, and it seems like you have a front end problem.
PHP 运行在后端,看来您的前端有问题。
I also doubt the problem is the input type you use. If one browser doesn't support the input type you specified, then it defaults to text. See it here:
我也怀疑问题是您使用的输入类型。如果某个浏览器不支持您指定的输入类型,则默认为文本。在这里看到它:
My browser doesn't know what the <input type="whatever" />
is, so it defaults the input type to "text". If I wrap those 4 inputs in a <form action="myForm.php" method="POST"></form>
tag, the browser sends the inputs to the server because the server doesn't care/know if the inputs were hidden, radio buttons, selects, texts, or password. The servers only receives raw-data.
我的浏览器不知道这<input type="whatever" />
是什么,所以它默认输入类型为“文本”。如果我将这 4 个输入包装在一个<form action="myForm.php" method="POST"></form>
标签中,浏览器会将输入发送到服务器,因为服务器不关心/知道输入是否隐藏、单选按钮、选择、文本或密码。服务器只接收原始数据。
More than likely, your issue is with your Javascript, and not with your PHP. Try to see if the browser that doesn't display your widget tells you that there's an error of some kind in your page.
很有可能,您的问题出在您的 Javascript 上,而不是出在您的 PHP 上。尝试查看未显示小部件的浏览器是否告诉您页面中存在某种错误。
Safari and Firefox have development/debugging tools, not so sure about IE.
Safari 和 Firefox 有开发/调试工具,对 IE 不太确定。
回答by Ilia Rostovtsev
Your regex didn't work because you had unescaped/
delimiter.
您的正则表达式不起作用,因为您有未转义的/
分隔符。
The regex that would validate date in format YYYY-MM-DD
as follows:
YYYY-MM-DD
以如下格式验证日期的正则表达式:
^(19|20)\d\d[\-\/.](0[1-9]|1[012])[\-\/.](0[1-9]|[12][0-9]|3[01])$
It will validate that the year starts with 19
or 20
, that the month is not greater than 12
and doesn't equal 0
and that the day is not greater than 31
and doesn't equal 0
.
它将验证年份以19
或开头,20
月份不大于12
且不等于0
,日期不大于31
且不等于0
。
Using your initial example, you could test it like this:
使用您的初始示例,您可以像这样测试它:
$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>';
}
回答by Vladislav Savchuk
Check and validate YYYY-MM-DD
date in one line statement
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;
}
See the details in my answer here.
请在此处查看我的回答中的详细信息。
Don't use blindly DateTime::createFromFormat
to validate dates. Let's take non-existent date 2018-02-30
and see:
不要盲目使用DateTime::createFromFormat
来验证日期。让我们以不存在的日期为例2018-02-30
,看看:
$d = DateTime::createFromFormat("Y-m-d", "2018-02-30");
var_dump((bool) $d); // bool(true)
Yes, it returns true
, not false
as you may expected. More interesting:
是的,它返回true
,false
与您预期的不同。更有意思的:
$d = DateTime::createFromFormat("Y-m-d", "2018-99-99");
var_dump((bool) $d); // bool(true)
Also true
... So, it validates just the number of digits. One more try:
也true
......所以,它只验证数字的数量。再试一次:
$d = DateTime::createFromFormat("Y-m-d", "ABCD-99-99");
var_dump($d); // bool(false)
At last false
.
最后false
。
What is going on here we can see from this snippet:
我们可以从这个片段中看到这里发生了什么:
$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"
}
As you can see when we pass non-existent 2018-02-30
, the DateTime
object contains 2018-03-02
. I assume that it's because February 2018 has 28 days, i.e. the maximum date is 2018-02-28
, and when we pass the day 30
, createFromFormat just adds 30 days to the 2018-02-01
and create new date without any preceding date validation.
正如您所看到的,当我们传递不存在时2018-02-30
,DateTime
对象包含2018-03-02
. 我认为这是因为 2018 年 2 月有 28 天,即最大日期是2018-02-28
,当我们通过这一天时30
,createFromFormat 只是将 30 天添加到2018-02-01
并创建新日期,而无需任何先前的日期验证。