PHP正则表达式检查日期是否为YYYY-MM-DD格式

130

我想检查最终用户输入的日期格式是否为YYYY-MM-DD。正则表达式从来不是我的强项,我设置的preg_match()一直返回false。

所以我认为我在正则表达式上搞砸了,详见下文。

$date="2012-09-12";

if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
    {
        return true;
    }else{
        return false;
    }

有什么想法吗?


6
正则表达式不足以验证日期。在使用正则表达式后,你还应该使用以下两种方式之一:date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12"; 或者 PHP 的 checkdate ( int $month , int $day , int $year ) - oxygen
1
我现在并不想验证它,我只是想确保它的格式为YYYY-MM-DD。 - cosmicsafari
2
对于用户输入的值,除了在表单提交后立即进行正则表达式检验(以便您可以显示错误消息)之外,还有什么更好的“时机”来验证呢? - oxygen
公正的观点,可以避免以后的小问题。 - cosmicsafari
27个回答

4
您也可以这样做:
if (DateTime::createFromFormat('Y-m-d', $date)->format('Y-m-d') === $date) {

    // date is correctly formatted and valid, execute some code

}

这将不仅检查格式,还将验证日期本身的有效性,因为 DateTime 只会创建有效的日期,而这需要与输入匹配。


4
您可以使用

标签。

function validateDate($date, $format = 'Y-m-d H:i:s')
{
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

$date="2012-09-12";    
echo validateDate($date, 'Y-m-d'); // true or false

3

格式1: $format1 = "2012-12-31";

格式2: $format2 = "31-12-2012";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$format1)) {
    return true;
} else {
    return false;
}

if (preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-[0-9]{4}$/",$format2)) {
    return true;
} else {
    return false;
}

2

如果您想匹配那种类型的日期,请使用:

preg_match("~^\d{4}-\d{2}-\d{2}$~", $date)

2

这应该告诉你格式是否有效,以及输入的日期是否有效。

    $datein = '2012-11-0';

    if(preg_match('/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/', $datein)){
        echo 'good';
    }else{
        echo 'no good';
    }

2

在一行语句中检查和验证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;
}

输出结果将是:
var_dump(isValidDate("2018-01-01")); // bool(true)
var_dump(isValidDate("2018-1-1"));   // bool(true)
var_dump(isValidDate("2018-02-28")); // bool(true)
var_dump(isValidDate("2018-02-30")); // bool(false)

允许使用没有前导零的日期和月份。如果不想允许此类情况,正则表达式应该是:

"/^(\d{4})-(\d{2})-(\d{2})$/"

2
以下内容确保数字为YYYY(1900-2099)-MM(01-12)-DD(01-31),同时利用checkdate()函数来验证日期的正确性,例如2月29日:
$date_pattern = '/^(19|20)\d{2}\-(0[1-9]|1[0-2])\-(0[1-9]|[12][0-9]|3[01])$/';

if (empty($date) || (!preg_match("$date_pattern", $date, $m) || (!checkdate($m[2], $m[3], $m[1])))) {
    echo 'Invalid Start date e.g. YYYY-MM-DD';
}

更改日期格式和年份范围:

// 格式为DD/MM/YYYY,其中DD(01-31),MM(01-12)和YYYY(1950-2099)必须是数字 - 将checkdate()替换为!checkdate($m[2], $m[1], $m[3]

// 扩展年份范围,例如1900-2099 /^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/(19|20)\d{2}$/ - 将checkdate()替换为!checkdate($m[2], $m[1], $m[3]


2

我正在搜索“如何验证日期”,并找到了这个解决方案。虽然它有点老,但是我将分享以下方法,可以在php中用于验证日期:

checkdate('01', '31', '2019')

1

这完全取决于您希望此功能有多严格。例如,如果您不想允许超过12个月和31天以上的日期(不考虑月份,这将需要编写日期逻辑),那么它可能会变得非常复杂:

function checkDate($date)
{
  $regex = '/^' . 
    '(' .

    // Allows years 0000-9999
    '(?:[0-9]{4})' .
    '\-' .

    // Allows 01-12
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)' .
    ')' .
    '\-' .

    // Allows 01-31
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)|(?:13)|(?:14)|(?:15)|(?:16)|(?:17)|(?:18)|(?:19)|(?:20)|' .
    '(?:21)|(?:22)|(?:23)|(?:24)|(?:25)|(?:26)|(?:27)|(?:28)|(?:29)|(?:30)|' .
    '(?:31)' .
    ')' .

    '$/';

  if ( preg_match($regex, $date) ) {
    return true;
  }

  return false;
}

$result = checkDate('2012-09-12');

个人而言,我只会选择:/^([0-9]{4}\-([0-9]{2}\-[0-9]{2})$/


7
这个正则表达式过于复杂了。0[1-9]|1[0-2] 匹配月份 01-12,而 0[1-9]|[12][0-9]|3[01] 则匹配日数 01-31。 - estrar
2
抱歉,我要吐了。 - AlxVallejo

1
如果有帮助的话,这是一个适用于j-n-Y格式的正则表达式(年份必须大于2018):
if (preg_match('/^([1-9]|[1-2][0-9]|[3][0-1])\-([1-9]|[1][0-2])\-(?:20)([1][8-9]|[2-9][0-9])$/', $date)) {
   // Do stuff
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接