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

спасибо, Лау

Ответ 1

Основано на решении, основанном на checkdate Tim:

Извлечение дня, месяца и года может быть легко выполнено с помощью explode как:

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

Ответ 2

Я бы предложил вместо 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 проверяет фактическую дату.

Ответ 3

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

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

Ответ 4

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 для проверки значений даты

Ответ 5

$ok  = DateTime::createFromFormat('d/m/Y',$datestring)->format('d/m/Y') == $datestring;

PHP >= 5.3

Ответ 6

Чтобы быть действительно анально-ретентивным, может быть проще использовать ваше текущее регулярное выражение, проанализировать числа, а затем проверить, что они находятся в диапазоне с checkdate(), но для kicks, здесь регулярное выражение, которое обеспечивает даты = 01-31 (и 1-9), и month = 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 ( )

Ответ 7

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

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

Ответ 8

Только принятие строго отформатированной строки, вероятно, является плохой практикой. Предполагая, что вы получаете ввод с веб-страницы, было бы лучше иметь отдельные поля для месяца, дня и года. Они могут быть текстовыми полями, но может быть предпочтительнее иметь раскрывающиеся меню, которые позволят решить проблему с ограничениями (т.е. Единственный выбор для месяца - 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."/>';
}

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

Ответ 9

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

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

$transformedDate = date("m/d/Y", strtotime($myDate));

if($transformedDate == $myDate){        
    return true;    
} else{         
    return false;           
}

Ответ 10

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

Ответ 11

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

    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;
    }

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

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

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

+ веселит

Ответ 12

Это самый простой способ решить вашу проблему.

preg_match("/^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$/", $date_string)

Дата выглядит как => 31/12/2019

Тестовая демонстрация