preg match: проверьте формат дня рождения (dd / mm/yyyy)

Как сделать выражение, которое проверяет ввод дня рождения, чтобы соответствовать формату, подобному этому 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 для mm? но я уверен, как ограничить гггг... Я думаю, что теоретический 9999 должен быть приемлемым... дайте мне знать, если у вас есть идея получше!

спасибо, Лау

11 ответов


на основе Тим ' s checkdate решение:

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

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(), но для пинки, вот регулярное выражение, которое гарантирует даты = 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";}

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

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

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

любезно следующие сообщения:

формат регулярного выражения здесь.. спасибо, Абин.

функция для проверки формата [здесь] (в CodeIgniter по regex матча) .. спасибо Ашем

+ура