preg_match: проверить формат дня рождения (дд / мм / гггг)

Как сделать выражение, которое проверяет вход дня рождения, чтобы соответствовать формату, подобному этому dd / mm / yyyy? Ниже я догадываюсь, но это занимает тоже, если я ставлю 99/99/9999!

if (!preg_match("/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/", $cnt_birthday)) { $error = true; echo '<error elementid="cnt_birthday" message="BIRTHDAY - Only this birthday format - dd/mm/yyyy - is accepted."/>'; } 

Как я могу убедиться, что его только от 01 до 31 для dd и от 01 до 12 для мм? но я уверен, как ограничить yyyy … Я думаю, что теоретический 9999 должен быть приемлемым … дайте мне знать, если у вас есть лучшая идея!

спасибо, Лау

Основываясь на решении Tim 's checkdate :

Добыть день, месяц и год можно легко, используя explode как:

 list($dd,$mm,$yyyy) = explode('/',$cnt_birthday); if (!checkdate($mm,$dd,$yyyy)) { $error = true; } 

Я бы предложил вместо этого использовать checkdate () :

 if (preg_match("/([0-9]{2})\/([0-9]{2})\/([0-9]{4})/", $cnt_birthday, $matches)) { if (!checkdate($matches[2], $matches[1], $matches[3])) { $error = true; echo '<error elementid="cnt_birthday" message="BIRTHDAY - Please enter a valid date in the format - dd/mm/yyyy"/>'; } } else { $error = true; echo '<error elementid="cnt_birthday" message="BIRTHDAY - Only this birthday format - dd/mm/yyyy - is accepted."/>'; } 

Поэтому regexp проверяет формат, checkdate проверяет фактическую дату.

Рассмотрим использование strtotime() и переформатируйте его с помощью date() . Это обеспечит большую гибкость для пользователей при вводе даты и позволит вам использовать любые форматы, которые вам нужны в разных местах.

Лично я довольно ленив, когда дело доходит до точного расчета даты и злоупотребляет им, как strtotime("-10 day",$timestamp) . Это имеет более низкую возможность получить иск от раздраженного родителя, потому что вы рассчитали возраст их дочерей до 18 лет, не считая правильных високосных лет, и пусть она попадет на ваш сайт для взрослых, как бы смешно это ни звучало.

 if(preg_match("/(\d{2})\/(\d{2})\/(\d{4})$/", $date,$matches)){ return (checkdate((int) $matches[2],(int)$matches[1],(int) $matches[3]) ); }else{ return false ; } 
  • preg_match для проверки шаблона dd / mm / yyyy
  • checkdate для проверки значений даты
 $ok = DateTime::createFromFormat('d/m/Y',$datestring)->format('d/m/Y') == $datestring; 

PHP> = 5.3

Чтобы быть действительно анально-ретентивным, может быть проще использовать текущее регулярное выражение, проанализировать числа, а затем проверить, что они находятся в диапазоне с checkdate () , но для kicks это регулярное выражение, которое обеспечивает даты = 01-31 (и 1- 9) и месяц = ​​01-12 (и 1-9) .

 preg_match("/([012]?[1-9]|[12]0|3[01])\/(0?[1-9]|1[012])\/([0-9]{4})/", $date_string) 

Пара примечаний

  • Я использовал группировку на всех, необходимых для ORing ( | ) внутри, но также полезен для извлечения этих значений, если вы хотите делать с ними определенные вещи
  • 0000 не имеет большого смысла в качестве даты, но я оставил взрыв этого регулярного выражения в качестве экстерьера для читателя. Если вы действительно хотите, чтобы это подтвердило даты рождения (и вы ожидаете, что в настоящее время или относительно недавно умершие люди), ограничьте это, чтобы сказать 1900+ или 1800+, или что-то приемлемое для вас. Если вы, возможно, разбираете дни рождения исторических фигур … ваш звонок.
  • Это все еще не проверяет правильность диапазона дат для соответствующего месяца! поэтому для этого используйте checkdate ()

возможно, что-то вроде этого поможет

  list($month,$day,$year)=explode("/",$date); if(checkdate($month,$day,$year)) { echo "good"; } else{echo "bad";} в  list($month,$day,$year)=explode("/",$date); if(checkdate($month,$day,$year)) { echo "good"; } else{echo "bad";} в  list($month,$day,$year)=explode("/",$date); if(checkdate($month,$day,$year)) { echo "good"; } else{echo "bad";} 

Только принятие строго отформатированной строки, вероятно, является плохой практикой. Предполагая, что вы получаете ввод с веб-страницы, было бы лучше иметь отдельные поля для месяца, дня и года. Они могут быть только текстовыми полями, но может быть предпочтительнее иметь раскрывающиеся меню, которые позволят решить вашу проблему с лимитами (т. Е. Выбор в месяц составляет 1,2, …, 12). Требование, чтобы пользователи вводили 01/01/2001 и не принимали 1/1/2001, – это ленивое программирование. И только прием «/» в качестве разделителя неудобен.

Но, чтобы затронуть свой первоначальный вопрос, даже если вы решите придерживаться форматированных строк – поскольку это поле даты рождения, вы должны, вероятно, ограничить yyyy:

 if($yyyy > date('Y')) { echo '<error elementid="cnt_birthday" message="BIRTHDAY - Year must be less than or equal to the current year."/>'; } 

В противном случае люди могут иметь отрицательные возрасты 🙂

Наверное, это не лучшее решение, но вот моя попытка.

Вы конвертируете его в определенное время, а затем переформатируете обратно в m / d / Y. Если строка не изменилась, значит, она была в правильном формате.

 $transformedDate = date("m/d/Y", strtotime($myDate)); if($transformedDate == $myDate){ return true; } else{ return false; } 

Попробуйте это регулярное выражение: ([0-9]{2}\/[0-9]{2}\/[0-9]{4})

Я опаздываю, чтобы увидеть это, но это решило мою проблему

  if (1 !== preg_match('/(0[1-9]|1[0-9]|2[0-9]|3(0|1))\/(0[1-9]|1[0-2])\/\d{4}/',$value)) { $this->form_validation->set_message('validate_emaildate','Date needs to have a valid date format - dd/mm/yyyy'); return FALSE; } 

Предоставлено следующие должности:

Формат Regex здесь .. спасибо Абин.

Функция для проверки формата [здесь] ( регулярное выражение Codeigniter ) .. спасибо Hashem

+ веселит