PHP Regex per controllare la data è nel formato AAAA-MM-GG


97

Sto cercando di controllare che le date inserite dagli utenti finali siano nel AAAA-MM-GG. Regex non è mai stato il mio punto di forza, continuo a ricevere un valore di ritorno falso per preg_match () che ho impostato.

Quindi presumo di aver combinato un pasticcio con la regex, descritta di seguito.

$date="2012-09-12";

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

qualche idea?


6
Regex non è sufficiente per convalidare una data. Dopo regex dovresti anche usare uno di questi due: date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12";o PHP checkdate ( int $month , int $day , int $year ).
Tiberiu-Ionuț Stan

Non sto cercando di convalidarlo a questo punto, voglio solo assicurarmi che sia nel formato AAAA-MM-GG.
cosmicsafari

2
Per un valore inserito da un utente, quale miglior "punto" nel tempo da convalidare se non subito dopo l'espressione regolare, al momento dell'invio del modulo (in modo da poter visualizzare un errore)?
Tiberiu-Ionuț Stan

Giusto punto, potrebbe salvare un intoppo più tardi.
cosmicsafari

Risposte:


196

Prova questo.

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

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
Perché è stata contrassegnata come risposta corretta? Restituisce vero per una serie di date non valide come 30/02/2016 e 31/09/2016
Graham

7
Questa domanda riguarda come controllare un formato di data (AAAA-MM-GG) e una risposta contrassegnata come accettata non è sempre la risposta migliore, significa solo che ha funzionato per la persona che ha chiesto, leggi questo bellissimo tour: stackoverflow. com / tour .
stramin

@Graham vecchio post lo so ma sono d'accordo con Stramin - questa domanda chiede sulla convalida del formato - non sulla convalida della data effettiva
treyBake

98

Probabilmente è meglio usare un altro meccanismo per questo.

La soluzione moderna, con DateTime:

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

Questo convalida anche l'input: $dt !== falseassicura che la data possa essere analizzata con il formato specificato e il array_sumtrucco è un modo conciso per garantire che PHP non abbia effettuato il "cambio di mese" (ad esempio, si consideri che il 32 gennaio è il 1 febbraio). Vedere DateTime::getLastErrors()per ulteriori informazioni.

Soluzione vecchia scuola con explodee checkdate:

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

Ciò conferma che anche l'input è una data valida. Puoi farlo con una regex ovviamente, ma sarà più complicato e il 29 febbraio non può essere convalidato affatto con un'espressione regolare.

Lo svantaggio di questo approccio è che devi stare molto attento a rifiutare tutti i possibili input "cattivi" senza emettere un avviso in nessuna circostanza. Ecco come:

  • explodeè limitato a restituire 3 gettoni (in modo che se l'input è "1-2-3-4", $ddiventerà "3-4")
  • ctype_digit viene utilizzato per assicurarsi che l'input non contenga caratteri non numerici (a parte i trattini)
  • array_padèusato (con un valore predefinito che farà checkdatefallire) per assicurarsi che vengano restituiti elementi sufficienti in modo che se l'ingresso è "1-2" list()non verrà emesso un avviso

+1, sempre usato DateTimee mai sentito parlare checkdate... peccato per me.
k102

@ k102: DateTimepuò anche fare questo. Ho appena finito di elaborare la risposta, dai un'occhiata di nuovo se vuoi.
Jon

Guardando il manuale PHP, sembra che la prima soluzione convaliderà le date incomplete (compilando i valori mancanti dalla data corrente).
user2428118

Un altro problema con la soluzione n. 1: "valori inesistenti rollover", ad esempio 2001-02-31 diventa 2001-03-03. (Sebbene l'OP non abbia chiesto esplicitamente che ciò non sia possibile.)
user2428118

1
@ user2428118: Hai provato la soluzione n. 1 esattamente come data, o solo la prima riga? Hai fatto clic sul collegamento che fornisco alla documentazione per getLastErrors?
Jon

42

aaaa-mm-gg: /^((((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 / gg: /^((((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-gg-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 / gg / 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

gg / 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

gg-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


Tutto ciò funziona per date dal 1900 al 9999 che è ciò che è necessario la maggior parte del tempo ed è 74 caratteri più breve del mio tentativo (nel formato aaaa-mm-gg). se vuoi date precedenti al 1900, una piccola modifica alla risposta di Shyju consentirà dall'anno 1000 ed è di altri 23 caratteri più breve: ^ ((([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

Criteri:

Ogni anno divisibile per 4 è un anno bisestile, tranne quando è divisibile per 100 a meno che non sia divisibile per 400. Quindi:

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

Febbraio ha 29 giorni in un anno bisestile e 28 quando non è un anno bisestile

30 giorni in aprile, giugno, settembre e novembre

31 giorni in gennaio, marzo, maggio, luglio, agosto, ottobre e dicembre

Test:

Le seguenti date dovrebbero tutte superare la convalida:

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

Le seguenti date dovrebbero non superare la convalida:

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

Gamma:

Verificheremo le date dal 1 ° gennaio 1000 al 31 dicembre 2999. Tecnicamente il calendario gregoriano attualmente utilizzato è entrato in uso solo nel 1753 per l'Impero britannico e in vari anni nel 1600 per i paesi in Europa, ma non ho intenzione di farlo preoccuparti di questo.

Regex da testare per un anno bisestile:

Gli anni divisibili per 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

Gli anni divisibili per 4:

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

Gli anni divisibili per 100:

[12]\d00

Non divisibile per 100:

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

Gli anni divisibili per 100 ma non per 400:

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

Divisibile per 4 ma non per 100:

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

Gli anni bisestili:

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])

Non divisibile per 4:

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

Non è un anno bisestile:

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

Mese e giorno validi escluso febbraio (MM-GG):

((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))

Febbraio con 28 giorni:

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

Febbraio con 29 giorni:

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

Data valida:

(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]))))

Quindi ecco una regex per le date tra il 1 ° gennaio 1000 e il 31 dicembre 2999 nel formato AAAA-MM-GG.

Sospetto che possa essere accorciato un po ', ma lo lascerò a qualcun altro.

Ciò corrisponderà a tutte le date valide. Se vuoi che sia valido solo quando contiene solo una data e nient'altro, inseriscilo in questo ^( )$modo:

^(((((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 lo desideri per una voce di data facoltativa (ad es. Può essere vuoto o una data valida), aggiungi ^$|all'inizio, in questo modo:

^$|^(((((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])))))$

7
Questa è un'espressione eroica e spiegata molto bene.
ambient

Hai una prova forte che supererà ogni caso valido e fallirà in ogni caso non valido?
Md Ashraful Islam il

@Md Ashraful Islam No
Graham

@Graham Anche se nessun problema, lo stiamo usando nel nostro sito web. Spero che non si verifichino problemi.
Md Ashraful Islam

@Md Ashraful Islam - Lo usiamo anche noi e finora non abbiamo avuto problemi con esso
Graham

18

Puoi farlo in questo modo:

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

ma faresti meglio a usare questo:

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

in questo caso otterrai un oggetto che è più facile da usare rispetto alle semplici stringhe.


1
La tecnica dateTime utilizzata qui restituirà vera per una data come 2016-05-44 che non è una data effettiva
nonybrighto

Questo non è un buon esempio soprattutto se vuoi ottenere la data (Ymd). Esempio: 0175-44-19927passerà.
Attila Naghi

7

So che questa è una vecchia domanda. Ma penso di avere una buona soluzione.

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

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

Puoi provarlo. Se si modifica la data in 21.02.2016, l'eco è falso. E se successivamente cambi il formato in dmY, l'eco è vero.

Con questo semplice codice dovresti essere in grado di controllare quale formato di data viene utilizzato senza controllarlo dalla regex.

Forse c'è una persona che lo metterà alla prova in ogni caso. Ma penso che la mia idea sia generalmente valida. Per me sembra logico.


Non penso che tu abbia bisogno di date () intorno a $ date sulla riga if. if (date ($ format, strtotime ($ date)) == $ date) - dovrebbe essere sufficiente
iateadonut

7

Puoi usare un preg_match con una funzione php checkdate

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

return preg_match ("/ ^ ([0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) $ /", $ date, $ split)) && checkdate ($ split [2], $ split [3], $ split [1]);
Tiberiu-Ionuț Stan

5

preg_match richiede un / o un altro carattere come delimitatore.

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

dovresti anche verificare la validità di quella data in modo da non finire con qualcosa come 9999-19-38

bool checkdate ( int $month , int $day , int $year )

3

Puoi anche farlo in questo modo:

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

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

}

Questo non solo controllerà il formato, ma anche la validità della data stessa, poiché DateTimecreerà solo date valide e questo deve corrispondere all'input.


3

Puoi usare

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

2

Controlla e convalida la YYYY-MM-DDdata in una riga

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

L'output sarà:

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)

Sono consentiti giorno e mese senza zero iniziale. Se non vuoi permetterlo, la regexp dovrebbe essere:

"/^(\d{4})-(\d{2})-(\d{2})$/"

1

Se vuoi abbinare quel tipo di data, usa:

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

1

Questo dovrebbe dirti se il formato è valido e se la data di input è valida.

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

1

Se è di qualche aiuto, ecco una regex per il formato jnY (l'anno deve essere maggiore del 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
}

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

1

Probabilmente utile a qualcuno:

$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

'1996-11-31 24:00'); // true, veramente? Inoltre, a volte ci sono 61 secondi in un minuto, vedi: en.wikipedia.org/wiki/Leap_second
Toto

1

Funzione per convalidare il formato della data generico:

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

Esempio di esecuzione:

var_dump(validateDate('2021-02-28')); // true
var_dump(validateDate('2021-02-29')); // false

Inserisci la tua risposta sempre nel contesto invece di incollare semplicemente il codice. Vedi qui per maggiori dettagli. Modifica anche la tua risposta per contenere tutte le parti del codice nel blocco
markdown

0

Tutto dipende da quanto rigorosa vuoi che questa funzione sia. Ad esempio, se non vuoi consentire mesi superiori a 12 e giorni superiori a 31 (non a seconda del mese, ciò richiederebbe la scrittura della logica della data), potrebbe diventare piuttosto complicato:

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');

Personalmente sceglierei solo: /^([0-9]{4}\-([0-9]{2}\-[0-9]{2})$/


4
Questa regex è inutilmente complicata. 0[1-9]|1[0-2]corrisponde al mese 01-12 e 0[1-9]|[12][0-9]|3[01]corrisponde al giorno 01-31.
estrar

Scusami mentre vomito
AlxVallejo

0

Per lavorare con le date in php dovresti seguire lo standard php in modo che la regex fornita assicuri che hai una data valida che può funzionare con PHP.

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

Il tuo rgex è sbagliato, non corrisponderà 1980-01-01ma corrisponderà2100-02-29
Toto

0

Questo metodo può essere utile per convalidare la data in PHP. Il metodo corrente è per il formato mm / gg / aaaa. Devi aggiornare la sequenza dei parametri in checkdate secondo il tuo formato e delimitatore in explode .

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

0

[Se usi Symfony 4.1.2 prova questo] [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');
        }

0

Da Laravel 5.7 e formato data, ovvero: 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);
}

0

Stavo cercando "come convalidare la data" e ho trovato questa soluzione, è vecchia ma condividerò di seguito il metodo che può essere utilizzato per convalidare la data in php,

checkdate('01', '31', '2019')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.