Регулярное выражение для проверки даты в PHP с использованием формата YYYY-MM-DD
Я пытаюсь сделать валидатор регулярных выражений даты. Проблема в том, что я использую поле ввода с типом "date", которое работает как шарм в Chrome; он открывает календарь, как в Chrome, но в остальном он ничего не делает, поэтому я решил пойти на ручной ввод даты для остальных.
Это мое сообщение об ошибке (я ищу YYYY-MM-DD формат):
$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 ответов:
Ваше регулярное выражение не работало, потому что у вас было unescaped
/разделитель.Регулярное выражение, которое будет проверять дату в формате
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>'; }
Не используйте для этого регулярное выражение, Вы можете получить тот же результат, используя
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" />, поэтому он по умолчанию вводит тип "текст". Если я оберну эти 4 входа в тег<form action="myForm.php" method="POST"></form>, браузер отправит входы на сервер, потому что сервер не заботится / не знает, были ли входы скрыты, переключатели, селекторы, тексты или пароль. Серверы получают только необработанные данные.Скорее всего, ваша проблема связана с вашим 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, ОбъектDateTimeсодержит2018-03-02. Я предполагаю, что это потому, что февраль 2018 года имеет 28 дней, т. е. максимальная дата -2018-02-28, и когда мы проходим день30, createFromFormat просто добавляет 30 дней к2018-02-01и создает новую дату без какой-либо предшествующей проверки даты.
Comments