Função para verificar se uma string é uma data

Estou tentando escrever uma function para determinar se uma string é uma data / hora usando o PHP. Basicamente, uma data / hora válida seria:

2012-06-14 01:46:28 

Obviamente, embora seja completamente dynamic, qualquer um dos valores pode mudar, mas sempre deve ser na forma de XXXX-XX-XX XX:XX:XX , como posso escrever uma expressão regular para verificar esse padrão e retornar verdadeiro se for correspondente.

Se essa for sua corda inteira, então tente analisá-la:

 if (DateTime::createFromFormat('Ymd G:i:s', $myString) !== FALSE) { // it's a date } 

Aqui está uma abordagem diferente sem usar uma regex:

 function check_your_datetime($x) { return (date('Ymd H:i:s', strtotime($x)) == $x); } 

Caso não conheça o formato da data:

 /** * Check if the value is a valid date * * @param mixed $value * * @return boolean */ function isDate($value) { if (!$value) { return false; } try { new \DateTime($value); return true; } catch (\Exception $e) { return false; } } var_dump(isDate('2017-01-06')); // true var_dump(isDate('2017-13-06')); // false var_dump(isDate('2017-02-06T04:20:33')); // true var_dump(isDate('2017/02/06')); // true var_dump(isDate('3.6. 2017')); // true var_dump(isDate(null)); // false var_dump(isDate(true)); // false var_dump(isDate(false)); // false var_dump(isDate('')); // false var_dump(isDate(45)); // false 

Eu uso essa function como um parâmetro para a function PHP filter_var .

  • Verifica datas em yyyy-mm-dd hh:mm:ss formato yyyy-mm-dd hh:mm:ss
  • Ele rejeita datas que combinam o padrão, mas ainda são inválidas (por exemplo, 31 de abril)

 function filter_mydate($s) { if (preg_match('@^(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)$@', $s, $m) == false) { return false; } if (checkdate($m[2], $m[3], $m[1]) == false || $m[4] >= 24 || $m[5] >= 60 || $m[6] >= 60) { return false; } return $s; } 

Embora isso tenha uma resposta aceita, não funcionará efetivamente em todos os casos. Por exemplo, eu teste a validação da data em um campo de formulário, eu usei a data “10/38/2013” e recebi um DateObject válido retornado, mas a data foi o que PHP chamou de “transbordou”, de modo que “10/38 / 2013 “torna-se” 11/07/2013 “. Faz sentido, mas devemos aceitar a data reformada ou forçar os usuários a inserir a data correta? Para aqueles de nós que são nazis de validação de formulário, podemos usar esta solução suja: https://stackoverflow.com/a/10120725/486863 e simplesmente retornar falso quando o object lança este aviso.

A outra solução seria combinar a data da string com a formatada e comparar os dois para o mesmo valor. Isso parece tão bagunçado. Ah bem. Tal é a natureza do desenv. PHP.

Eu não usaria um Regex para isso, mas simplesmente dividi a string e verifique se a data é válida:

 list($year, $month, $day, $hour, $minute, $second) = preg_split('%( |-|:)%', $mydatestring); if(!checkdate($month, $day, $year)) { /* print error */ } /* check $hour, $minute and $second etc */ 

strtotime ? Listas? Expressões regulares?

O que há de errado com o object DateTime nativo do PHP?

http://www.php.net/manual/en/datetime.construct.php

Se o seu coração estiver configurado ao usar o regEx, então txt2re.com é sempre um bom recurso:

 < ?php $txt='2012-06-14 01:46:28'; $re1='((?:2|1)\\d{3}(?:-|\\/)(?:(?:0[1-9])|(?:1[0-2]))(?:-|\\/)(?:(?:0[1-9])|(?:[1-2][0-9])|(?:3[0-1]))(?:T|\\s)(?:(?:[0-1][0-9])|(?:2[0-3])):(?:[0-5][0-9]):(?:[0-5][0-9]))'; # Time Stamp 1 if ($c=preg_match_all ("/".$re1."/is", $txt, $matches)) { $timestamp1=$matches[1][0]; print "($timestamp1) \n"; } ?> 

Se você tiver o PHP 5.2, a resposta de Joey não funcionará. Você precisa estender a class DateTime do PHP:

 class ExDateTime extends DateTime{ public static function createFromFormat($frmt,$time,$timezone=null){ $v = explode('.', phpversion()); if(!$timezone) $timezone = new DateTimeZone(date_default_timezone_get()); if(((int)$v[0]>=5&&(int)$v[1]>=2&&(int)$v[2]>17)){ return parent::createFromFormat($frmt,$time,$timezone); } return new DateTime(date($frmt, strtotime($time)), $timezone); } } 

e do que você pode usar esta class sem problemas:

 ExDateTime::createFromFormat('dmY G:i',$timevar); 
  function validateDate($date, $format = 'Ymd H:i:s') { $d = DateTime::createFromFormat($format, $date); return $d && $d->format($format) == $date; } 

a function foi copiada dessa resposta ou php.net

Uma versão menor, pode ajudar:

 if(strtotime($date_string)){ // it's in date format }