Регулярное выражение для проверки даты в 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. Смотрите здесь:
мой браузер не знает, что такое <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
на