简体   繁体   English

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

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

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; 我遇到的问题是我使用的是带有"date"类型的输入字段,它就像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. 它在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. 我知道有很多关于这方面的例子,但我已经尝试了20个,我无法解决它。 Maybe I'm missing something. 也许我错过了什么。

Here's the input field, if somewhat relevant: 这是输入字段,如果有些相关:

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

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: 在这里看到:

http://jsfiddle.net/FKGCA/ http://jsfiddle.net/FKGCA/

My browser doesn't know what the <input type="whatever" /> is, so it defaults the input type to "text". 我的浏览器不知道<input type="whatever" /><input type="whatever" /> ,因此它将输入类型默认为“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. 如果我将这4个输入包装在<form action="myForm.php" method="POST"></form>标记中,浏览器会将输入发送到服务器,因为服务器不关心/知道输入是否是隐藏,单选按钮,选择,文本或密码。 The servers only receives raw-data. 服务器只接收原始数据。

More than likely, your issue is with your Javascript, and not with your PHP. 更有可能的是,您的问题在于您的Javascript,而不是您的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. 尝试查看未显示小部件的浏览器是否告诉您页面中存在某种错误。

Safari and Firefox have development/debugging tools, not so sure about IE. Safari和Firefox都有开发/调试工具,对IE不太确定。

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 . 它将验证年份从1920开始,月份不大于12且不等于0且日期不大于31且不等于0

Example Online 在线示例

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>';      
}

Example Online 在线示例

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. 不要盲目使用DateTime::createFromFormat来验证日期。 Let's take non-existent date 2018-02-30 and see: 让我们看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. 是的,它会返回true ,而不是您所预期的false More interesting: 更有趣的:

$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. 也是true ......所以,它只验证了位数。 One more try: 再试一次:

$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 . 正如您所看到的,当我们传递不存在的2018-02-30DateTime对象包含2018-03-02 I assume that it's because February 2018 has 28 days, ie 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年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