2017-06-14 4 views
1

Je dois valider un format de date précis en PHP.Comment valider les dates sans indiquer de zéro le jour et le mois?

Dans mon cas, le format de date optimal devrait être: par ex. 1/1/2017 (sans les zéros en tête) et le code devrait me permettre d'éviter le reste du format de la date.

Le code suivant est ce que je l'ai écrit, mais sans résultat:

if(preg_match("/([1-9]|[1-2][0-9]|3[0-1]-([1-9]|1[0-2])-^[0-9]{4})$/", $date){ 
    // insert into etc. etc.... 
}else{ 
    // update etc. etc.... 
} 

Le problème est que le code ne valide pas correctement la date; il accepte tous les types de format de date.

+2

Voir ['date_parse_from_format()'] (http://php.net/manual/fr/function.date-parse-from-format.php). –

+0

ou ['strptime()'] (http://php.net/manual/en/function.strptime.php). –

+1

Bien sûr, vous pouvez utiliser regex pour ce faire. D'un autre côté, vous pouvez aussi utiliser regex pour analyser un arbre DOM entier qui ne veut pas dire que vous devriez le faire. – apokryfos

Répondre

1

J'ai remarqué que la réponse soumise par l'OP n'était pas pare-balles, donc j'ai commencé à rechercher certaines des fonctions mentionnées dans les commentaires sous la question et certains de mes propres pensées

Je suis d'accord avec apokryfos en ce que en utilisant regex pour valider une expression date n'est pas meilleur actice. Une solution purement rationnelle va être un modèle de plus en plus verbeux et de moins en moins compréhensible, car elle devra tenir compte des années bissextiles à la fois dans le passé et dans le futur. Pour cette raison, j'ai étudié quelques fonctions de date que php propose.

  1. date_parse_from_format() comme suggéré par Alex Howansky. Malheureusement, il ne sera pas un paramètre solution autonome pour ce cas parce que le format obéit à la syntaxe/règles de DateTime::createFromFormat():

enter image description here

Voyez comment d et j sont regroupées, comme le sont m et n. Par conséquent, cette fonction interceptera les dates non valides, mais pas les zéros non désirés.

  1. strptime() comme suggéré par Casimir et Hippolyte. Cette fonction fournit des jours correspondants sans zéros en utilisant %e. Cette fonction n'a pas de caractère correspondant aux numéros de mois non-zéro. En outre, il peut y avoir des problèmes de base avec cette fonction sur le système d'exploitation. Cela ressemble à un choix logique, mais encore une fois, il ne flanchera pas avec les nombres à zéro. De plus, cette fonction nécessite un peu plus de préparation de données que les autres, car elle nécessite d'individualiser les valeurs du mois, du jour et de l'année.

  2. if(!DateTime::createFromFormat('j/n/Y', $date)) suggéré par deceze concernant a slightly different scenario ne fonctionnera pas dans ce cas. createFromFormat() ira à de grandes longueurs pour construire une date valide - même une chaîne comme 99/99/9999 passera à travers.


Pour tenter de créer l'expression la plus concise, voici ce que je peux offrir comme solution apparemment pare-balles en utilisant une classe DateTime:

if (($d=DateTime::createFromFormat('n/j/Y',$date)) && $date==$d->format('n/j/Y')){ 
    // valid 
}else{ 
    // invalid 
} 

strtotime() peut être utilisé avec une seule condition pour ce cas car le format de date de l'OP utilise des barres obliques comme délimiteur et cette fonction va correctement analyser l'expression de date "à l'américaine".

Cela semble être la façon la plus simple de vérifier une date valide sans zéros: Demo Link

if(date('n/j/Y',strtotime($date))==$date){ 
    // valid 
}else{ 
    // invalid 
} 

Si vous avez affaire à des expressions datetime et ne souhaitez pas vérifier le temps partie, vous pouvez appeler cette ligne avant la ligne conditionnelle:

$date=explode(' ',$date)[0]; // trim time from datetime expressions 

Demo Link

2

Votre delimiter date est / et non -, il faut donc ajouter à \/ regex pour /. Et utiliser ^ au début de regex:

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

Après plusieurs heures, enfin je l'ai trouvé la bonne réponse. Le modèle correct pour php est d'utiliser les guillemets simples (') et non le guillemet ("), par exemple:

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

cela fonctionne bien pour moi ... Merci tout le monde surtout à @Mohammad Hamedani parce que l'expression était correct mais la citation de f ****** me rend folle

+0

Ouais tu as raison, je vais changer la coche verte;). Et merci beaucoup pour votre réponse complète –