PHP Regex para verificar a data está no formato AAAA-MM-DD

97

Estou tentando verificar se as datas inseridas pelos usuários finais estão no AAAA-MM-DD. Regex nunca foi meu ponto forte, continuo recebendo um valor de retorno falso para preg_match () que configurei.

Portanto, estou assumindo que baguncei a regex, detalhada abaixo.

$date="2012-09-12";

if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
    {
        return true;
    }else{
        return false;
    }

Alguma ideia?

cosmicsafari
fonte
6
Regex não é suficiente para validar uma data. Após regex, você também deve usar um destes dois: date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12";ou PHP checkdate ( int $month , int $day , int $year ).
Tiberiu-Ionuț Stan
Não estou tentando validá-lo neste momento, só quero ter certeza de que está no formato AAAA-MM-DD.
cosmicsafari
2
Para um valor inserido pelo usuário, que melhor "ponto" no tempo para validar, senão logo após a regex, no envio do formulário (para que você possa exibir um erro)?
Tiberiu-Ionuț Stan
Ponto justo, poderia salvar um hickup mais tarde.
cosmicsafari

Respostas:

196

Experimente isso.

$date="2012-09-12";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
    return true;
} else {
    return false;
}
Avin Varghese
fonte
18
return (bool)preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date);
Tiberiu-Ionuț Stan
5
Por que esta foi marcada como a resposta correta? Isso retorna verdadeiro para uma série de datas inválidas, como 2016-02-30 e 2016-09-31
Graham,
7
Esta pergunta é sobre como verificar um formato de data (AAAA-MM-DD), e uma resposta marcada como aceita nem sempre é a melhor resposta, significa apenas que funcionou para a pessoa que perguntou, leia este lindo tour: stackoverflow. com / tour .
stramin de
Postagem antiga de @Graham eu sei, mas concordo com Stramin - esta questão pergunta sobre a validação de formato - não a validação de data real
treyBake
98

É provavelmente melhor usar outro mecanismo para isso.

A solução moderna, com DateTime:

$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());

Isso valida a entrada também: $dt !== falsegarante que a data possa ser analisada com o formato especificado e o array_sumtruque é uma maneira concisa de garantir que o PHP não fez "mudança de mês" (por exemplo, considere que 32 de janeiro é 1 de fevereiro). Veja DateTime::getLastErrors()para mais informações.

Solução da velha escola com explodee checkdate:

list($y, $m, $d) = array_pad(explode('-', $date, 3), 3, 0);
return ctype_digit("$y$m$d") && checkdate($m, $d, $y);

Isso valida que a entrada também é uma data válida. Você pode fazer isso com uma regex, é claro, mas será mais complicado - e 29 de fevereiro não pode ser validado com uma regex.

A desvantagem dessa abordagem é que você deve ter muito cuidado para rejeitar todas as entradas "ruins" possíveis e, ao mesmo tempo, não emitir um aviso em nenhuma circunstância. Veja como:

  • explodeestá limitado a retornar 3 tokens (de modo que se a entrada for "1-2-3-4", $dse tornará "3-4")
  • ctype_digit é usado para garantir que a entrada não contenha caracteres não numéricos (além dos travessões)
  • array_padé usado (com um valor padrão que fará com checkdateque falhe) para garantir que elementos suficientes sejam retornados para que se a entrada for "1-2" list()não emita um aviso
Jon
fonte
+1, sempre usei DateTimee nunca ouvi falar checkdate... que vergonha.
k102
@ k102: DateTimetambém pode fazer isso. Acabei de definir a resposta, dê uma olhada novamente se quiser.
Jon
Olhando para o manual do PHP, parece que a primeira solução irá validar datas incompletas (preenchendo os valores faltantes da data atual).
user2428118
Outro problema com a solução # 1: "valores inexistentes rolam", por exemplo, 2001-02-31 torna-se 2001-03-03. (Embora o OP não tenha perguntado explicitamente que isso não é possível.)
user2428118
1
@ user2428118: Você tentou a solução nº 1 exatamente como fornecida ou apenas a primeira linha? Você clicou no link que forneço para a documentação de getLastErrors?
Jon
42

aaaa-mm-dd: /^((((19|[2-9]\d)\d{2})\-(0[13578]|1[02])\-(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\-(0[13456789]|1[012])\-(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\-02\-(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\-02\-29))$/g

aaaa / mm / dd: /^((((19|[2-9]\d)\d{2})\/(0[13578]|1[02])\/(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\/(0[13456789]|1[012])\/(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\/02\/(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\/02\/29))$/g

mm-dd-aaaa: /^(((0[13578]|1[02])\-(0[1-9]|[12]\d|3[01])\-((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\-(0[1-9]|[12]\d|30)\-((19|[2-9]\d)\d{2}))|(02\-(0[1-9]|1\d|2[0-8])\-((19|[2-9]\d)\d{2}))|(02\-29\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

mm / dd / aaaa: /^(((0[13578]|1[02])\/(0[1-9]|[12]\d|3[01])\/((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\/(0[1-9]|[12]\d|30)\/((19|[2-9]\d)\d{2}))|(02\/(0[1-9]|1\d|2[0-8])\/((19|[2-9]\d)\d{2}))|(02\/29\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

dd / mm / aaaa: /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

dd-mm-aaaa: /^(((0[1-9]|[12]\d|3[01])\-(0[13578]|1[02])\-((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\-(0[13456789]|1[012])\-((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\-02\-((19|[2-9]\d)\d{2}))|(29\-02\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

Shyju KP
fonte
O trabalho acima de tudo para datas de 1900 a 9999 que é o que é necessário na maioria das vezes e é 74 caracteres mais curto do que a minha tentativa (no formato aaaa-mm-dd). se você quiser datas anteriores a 1900, um pequeno ajuste na resposta de Shyju permitirá a partir do ano 1000 e outros 23 caracteres a menos: ^ ((([1-9] \ d {3}) \ - (0 [13578] | 1 [02]) \ - (0 [1-9] | [12] \ d | 3 [01])) | (((19 | [2-9] \ d) \ d {2}) \ - ( 0 [13456789] | 1 [012]) \ - (0 [1-9] | [12] \ d | 30)) | (([1-9] \ d {3}) \ - 02 \ - (0 [1-9] | 1 \ d | 2 [0-8])) | (([1-9] \ d (0 [48] | [2468] [048] | [13579] [26]) | ( (16 | [2468] [048] | [3579] [26]) 00))) \ - 02 \ -29)) $
Graham
36

Critério:

Cada ano divisível por 4 é um ano bissexto, exceto quando é divisível por 100, a menos que seja divisível por 400. Então:

2004 - leap year - divisible by 4
1900 - not a leap year - divisible by 4, but also divisible by 100
2000 - leap year - divisible by 4, also divisible by 100, but divisible by 400

Fevereiro tem 29 dias em um ano bissexto e 28 dias quando não é um ano bissexto

30 dias em abril, junho, setembro e novembro

31 dias em janeiro, março, maio, julho, agosto, outubro e dezembro

Teste:

As seguintes datas devem passar na validação:

1976-02-29
2000-02-29
2004-02-29
1999-01-31

As seguintes datas devem falhar na validação:

2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00

Alcance:

Vamos testar as datas de 1º de janeiro de 1000 a 31 de dezembro de 2999. Tecnicamente, o calendário gregoriano usado atualmente só entrou em uso em 1753 para o Império Britânico e em vários anos de 1600 para países da Europa, mas não vou se preocupe com isso.

Regex para testar em um ano bissexto:

Os anos divisíveis por 400:

1200|1600|2000|2400|2800
can be shortened to:
(1[26]|2[048])00

if you wanted all years from 1AD to 9999 then this would do it:
(0[48]|[13579][26]|[2468][048])00
if you're happy with accepting 0000 as a valid year then it can be shortened:
([13579][26]|[02468][048])00

Os anos são divisíveis por 4:

[12]\d([02468][048]|[13579][26])

Os anos divisíveis por 100:

[12]\d00

Não divisível por 100:

[12]\d([1-9]\d|\d[1-9])

Os anos divisíveis por 100, mas não por 400:

((1[1345789])|(2[1235679]))00

Divisível por 4, mas não por 100:

[12]\d([2468][048]|[13579][26]|0[48])

Os anos bissextos:

divisible by 400 or (divisible by 4 and not divisible by 100)
((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48])

Não divisível por 4:

[12]\d([02468][1235679]|[13579][01345789])

Não é um ano bissexto:

Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)

Mês e dia válidos, exceto fevereiro (MM-DD):

((01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|((04|06|09|11)-(0[1-9]|[12]\d|30))
shortened to:
((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30))

Fevereiro com 28 dias:

02-(0[1-9]|1\d|2[0-8])

Fevereiro com 29 dias:

02-(0[1-9]|[12]\d)

Data válida:

(leap year followed by (valid month-day-excluding-february OR 29-day-february)) 
OR
(non leap year followed by (valid month-day-excluding-february OR 28-day-february))

((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8]))))

Então, você tem uma regex para datas entre 1º de janeiro de 1000 e 31 de dezembro de 2999 no formato AAAA-MM-DD.

Suspeito que pode ser um pouco abreviado, mas deixarei isso para outra pessoa.

Isso corresponderá a todas as datas válidas. Se você quiser que seja válido apenas quando contiver apenas uma data e nada mais, envolva-o ^( )$assim:

^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$

Se você quiser uma entrada de data opcional (ou seja, pode estar em branco ou uma data válida), adicione ^$|no início, assim:

^$|^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$
Graham
fonte
7
É uma expressão heróica e muito bem explicada.
ambiente de
Você tem fortes provas de que ele passará em todos os casos válidos e falhará em todos os casos inválidos?
Md Ashraful Islam
@Md Ashraful Islam No
Graham
@Graham Embora não haja problema, estamos usando em nosso site. Espero que nenhum problema ocorra.
Md Ashraful Islam
@Md Ashraful Islam - Nós também o usamos e não tivemos nenhum problema com ele até agora
Graham
18

Você pode fazer desta forma:

if (preg_match("/\d{4}\-\d{2}-\d{2}/", $date)) {
    echo 'true';
} else {
    echo 'false';
}

mas é melhor você usar este:

$date = DateTime::createFromFormat('Y-m-d', $date);
if ($date) {
    echo $date -> format('Y-m-d');
}

neste caso, você obterá um objeto que é muito mais fácil de usar do que apenas cordas.

k102
fonte
1
A técnica dateTime usada aqui retornará verdadeira para uma data como 2016-05-44, que não é uma data real
nonybrighto
Este não é um bom exemplo, especialmente se você deseja obter a data (Ymd). Exemplo: 0175-44-19927vai passar.
Attila Naghi
7

Eu sei que esta é uma questão antiga. Mas acho que tenho uma boa solução.

$date = "2016-02-21";
$format = "Y-m-d";

if(date($format, strtotime($date)) == date($date)) {
    echo "true";
} else {
    echo "false";
}

Você pode experimentá-lo. Se você alterar a data para 21/02/2016, o eco será falso. E se você alterar o formato depois disso para dmY, o eco será verdadeiro.

Com esse código fácil, você deve ser capaz de verificar qual formato de data é usado sem verificar pelo regex.

Talvez haja uma pessoa que irá testá-lo em todos os casos. Mas acho que minha ideia é geralmente válida. Para mim, parece lógico.

Micha93
fonte
Não acho que você precise de date () por volta de $ date na linha if. if (date ($ format, strtotime ($ date)) == $ date) - deve ser suficiente
iateadonut
7

Você pode usar um preg_match com uma função checkdate php

$date  = "2012-10-05";
$split = array();
if (preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $split))
{
    return checkdate($split[2], $split[3], $split[1]);
}

return false;
Jonathan Muller
fonte
return preg_match ("/ ^ ([0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) $ /", $ date, $ split)) && data de verificação ($ split [2], $ split [3], $ split [1]);
Tiberiu-Ionuț Stan
5

preg_match precisa de um / ou outro caractere como delimitador.

preg_match("/^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$/",$date)

você também deve verificar a validade dessa data para que não termine com algo como 9999-19-38

bool checkdate ( int $month , int $day , int $year )
marianboda
fonte
3

Você também pode fazer assim:

if (DateTime::createFromFormat('Y-m-d', $date)->format('Y-m-d') === $date) {

    // date is correctly formatted and valid, execute some code

}

Isso não apenas verificará o formato, mas também a validade da própria data, pois DateTimecriará apenas datas válidas e isso precisa corresponder à entrada.

Kasimir
fonte
3

você pode usar

function validateDate($date, $format = 'Y-m-d H:i:s')
{
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

$date="2012-09-12";    
echo validateDate($date, 'Y-m-d'); // true or false
macaco
fonte
2

Verifique e valide a YYYY-MM-DDdata em uma instrução de linha

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

O resultado será:

var_dump(isValidDate("2018-01-01")); // bool(true)
var_dump(isValidDate("2018-1-1"));   // bool(true)
var_dump(isValidDate("2018-02-28")); // bool(true)
var_dump(isValidDate("2018-02-30")); // bool(false)

Dia e mês sem zero à esquerda são permitidos. Se você não quiser permitir isso, a regexp deve ser:

"/^(\d{4})-(\d{2})-(\d{2})$/"
Vladislav Savchuk
fonte
1

Se você quiser combinar esse tipo de data, use:

preg_match("~^\d{4}-\d{2}-\d{2}$~", $date)
ujovlado
fonte
1

Isso deve informar se o formato é válido e se a data de entrada é válida.

    $datein = '2012-11-0';

    if(preg_match('/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/', $datein)){
        echo 'good';
    }else{
        echo 'no good';
    }
Kenzo
fonte
1

Se for de alguma ajuda, aqui está uma regex para o formato jnY (o ano deve ser maior que 2018):

if (preg_match('/^([1-9]|[1-2][0-9]|[3][0-1])\-([1-9]|[1][0-2])\-(?:20)([1][8-9]|[2-9][0-9])$/', $date)) {
   // Do stuff
}
Filip
fonte
1

Formato 1: $ format1 = "2012-12-31";

Formato 2: $ format2 = "31-12-2012";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$format1)) {
    return true;
} else {
    return false;
}

if (preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-[0-9]{4}$/",$format2)) {
    return true;
} else {
    return false;
}
Hasib Kamal
fonte
1

Provavelmente útil para alguém:

$patterns = array(
            'Y'           =>'/^[0-9]{4}$/',
            'Y-m'         =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])$/',
            'Y-m-d'       =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$/',
            'Y-m-d H'     =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4])$/',
            'Y-m-d H:i'   =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?(0|[0-5][0-9]|60)$/',
            'Y-m-d H:i:s' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?((0|[0-5][0-9]):?(0|[0-5][0-9])|6000|60:00)$/',
        );
echo preg_match($patterns['Y'], '1996'); // true
echo preg_match($patterns['Y'], '19966'); // false
echo preg_match($patterns['Y'], '199z'); // false
echo preg_match($patterns['Y-m'], '1996-0'); // false
echo preg_match($patterns['Y-m'], '1996-09'); // true
echo preg_match($patterns['Y-m'], '1996-1'); // true
echo preg_match($patterns['Y-m'], '1996/1'); // true
echo preg_match($patterns['Y-m'], '1996/12'); // true
echo preg_match($patterns['Y-m'], '1996/13'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-1'); // true
echo preg_match($patterns['Y-m-d'], '1996-11-0'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-32'); // false
echo preg_match($patterns['Y-m-d H'], '1996-11-31 0'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 00'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 24'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 25'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 2400'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:00'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:59'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:60'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:6000'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:00'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:59'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:60'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:01'); // false
o manh Nguyen
fonte
'1996-11-31 24:00'); // true, realmente? Além disso, às vezes há 61 segundos em um minuto, consulte: en.wikipedia.org/wiki/Leap_second
Toto
1

Função para validar o formato de data genérico:

function validateDate($date, $format = 'Y-m-d') {
  $d = DateTime::createFromFormat($format, $date);
  return $d && $d->format($format) == $date;
}

Exemplo de execução:

var_dump(validateDate('2021-02-28')); // true
var_dump(validateDate('2021-02-29')); // false
Sharad Pawar
fonte
Por favor, coloque sua resposta sempre no contexto, em vez de apenas colar o código. Veja aqui para mais detalhes. Edite também sua resposta para conter todas as partes do código no bloco de redução
gehbiszumeis
0

Tudo depende de quão restrita você deseja que esta função seja. Por exemplo, se você não quiser permitir meses acima de 12 e dias acima de 31 (não dependendo do mês, isso exigiria escrever lógica de data), pode se tornar muito complicado:

function checkDate($date)
{
  $regex = '/^' . 
    '(' .

    // Allows years 0000-9999
    '(?:[0-9]{4})' .
    '\-' .

    // Allows 01-12
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)' .
    ')' .
    '\-' .

    // Allows 01-31
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)|(?:13)|(?:14)|(?:15)|(?:16)|(?:17)|(?:18)|(?:19)|(?:20)|' .
    '(?:21)|(?:22)|(?:23)|(?:24)|(?:25)|(?:26)|(?:27)|(?:28)|(?:29)|(?:30)|' .
    '(?:31)' .
    ')' .

    '$/';

  if ( preg_match($regex, $date) ) {
    return true;
  }

  return false;
}

$result = checkDate('2012-09-12');

Pessoalmente, eu só escolheria: /^([0-9]{4}\-([0-9]{2}\-[0-9]{2})$/

Ariaan
fonte
4
Esta regex é desnecessariamente complicada. 0[1-9]|1[0-2]corresponde ao mês 01-12 e ao 0[1-9]|[12][0-9]|3[01]dia 01-31.
estrar
Com licença enquanto eu vomito
AlxVallejo
0

Para trabalhar com datas em php, você deve seguir o padrão php para que a regex fornecida garanta que você tenha uma data válida que possa operar com PHP.

    preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)
Pratik Soni
fonte
Seu rgex está errado, ele não corresponderá, 1980-01-01mas será compatível2100-02-29
Toto
0

Este método pode ser útil para validar datas em PHP. O método atual é para o formato mm / dd / aaaa. Você deve atualizar a sequência de parâmetros em data de verificação de acordo com seu formato e delimitador em explodir .

    function isValidDate($dt)
    {
        $dtArr = explode('/', $dt);
        if (!empty($dtArr[0]) && !empty($dtArr[1]) && !empty($dtArr[2])) {
            return checkdate((int) $dtArr[0], (int) $dtArr[1], (int) $dtArr[2]);
        } else {
            return false;
        }
    }
Amit Garg
fonte
0

[Se você usa Symfony 4.1.2, tente isso] [1]

  $validDate = explode("-",$request->get('date'));
        if (checkdate(filter_var($validDate[1],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[0],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[2],FILTER_SANITIZE_NUMBER_INT))){
            $date = date_create(filter_var($request->get('date'),FILTER_SANITIZE_SPECIAL_CHARS));
        }else{
            return $this->redirectToRoute('YOUR_ROUTE');
        }
DIDIT B
fonte
0

Do Laravel 5.7 e formato de data, ou seja: 31/12/2019

function checkDateFormat(string $date): bool
{
    return preg_match("/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/[0-9]{4}$/", $date);
}
Mexidense
fonte
0

Eu estava pesquisando "como validar data" e encontrei esta solução, é antigo, mas vou compartilhar abaixo o método que pode ser usado para validar data em php,

checkdate('01', '31', '2019')
Parvez Alam
fonte