Регулярное выражение для проверки даты в PHP с использованием формата YYYY-MM-DD

Я пытаюсь сделать валидатор регулярных выражений даты. Проблема в том, что я использую поле ввода с "date" тип, который работает как шарм в Chrome; он открывает календарь, как в Chrome, но в остальном он ничего не делает, поэтому я решил пойти на ручной ввод даты для остальных.

Это мое сообщение об ошибке (я ищу формат гггг-ММ-ДД):

$date_regex ='#^(19|20)dd[- /.](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" />

3 ответов


ваше регулярное выражение не сработало, потому что у тебя неэкранированные / разделитель.

регулярное выражение, которое будет проверять дату в формате 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>';      
}

Пример Онлайн


не использовать regex для этого, вы можете получить тот же результат с помощью 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 работает на заднем конце, и кажется, что у вас есть проблема с передним концом.

Я тоже сомневаюсь, что проблема в типе ввода, который вы используете. Если один браузер не поддерживает тип ввода, который вы указали, по умолчанию-text. Смотрите здесь:

http://jsfiddle.net/FKGCA/

мой браузер не знает, что такое <input type="whatever" /> is, поэтому он по умолчанию вводит тип "текст". Если я оберну эти 4 входа в <form action="myForm.php" method="POST"></form> тег, браузер отправляет входы на сервер, потому что сервер не заботится/знает, были ли входы скрыты, переключатели, выбор, тексты или пароль. Серверы получают только raw-данные.

более чем вероятно, ваша проблема связана с вашим Javascript, а не с вашим PHP. Попробовать, чтобы увидеть, если браузер не отображает виджет говорит вам, что есть какая-то ошибка на странице.

Safari и Firefox имеют инструменты разработки / отладки, не так уверены в IE.


проверки 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 на