Test si une date au format français est valide

Contenu du snippet

Bon, c'est un cas extrême d'utilisation d'expression régulière. Plus un cas d'école, assez instructif, que quelque chose que j'utiliserai vraiment.
Je prêche plutôt de scinder une chaîne complexe en parties plus simples et d'utiliser du code pour vérifier les parties (avec ou sans expression régulière !).

Le but ici est de tester si une date du style jj/mm/aaaa est valide. Facile ? Pas si vous voulez rejeter les dates 29/02/2001 ou 31/11/2008... La validité se "limite" de 1600 à 2999.

Pour être honnête, la base a été écrite par un certain dany.lauener(at)b-i.com. Elle faisait 281 caractères de long. Je l'ai améliorée un peu : analysée en code étendu commenté ci-dessous, puis simplifié à 233 caractères, pour la même fonctionnalité.

J'espère qu'elle vous amusera, voire vous apprendra quelques astuces.

Source / Exemple :


L'expression brute :

^((0[1-9]|1\d|2[0-8])/(0\d|1[012])/(1[6-9]|[2-9]\d)\d{2}|(29|30)/(0[13-9]|1[012])/(1[6-9]|[2-9]\d)\d{2}|31/(0[13578]|1[02])/(1[6-9]|[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))$

La même, décortiquée (option PCRE_EXTENDED par exemple : espaces non significatifs, le texte après # est du commentaire) :

^(
   # Jours 01 à 28, tous mois, toutes années : prend en compte rapidement les cas les plus courants
   ( # Jours 01 à 28
      0[1-9]
      |
      1\d
      |
      2[0-8]
   )
   /
   ( # Mois (quelconques)
      0\d
      |
      1[012]
   )
   /
   ( # Années (n'importe lesquelles)
      1[6-9] # 1600 à 1999
      |
      [2-9]\d # 2000 à 9999
   )\d{2} # N'importe quelle paire de chiffres

   |

   # Cas des mois avec 30 jours (ou moins)
   ( # 29 ou 30
      29
      |
      30
   )
   /
   ( # Mois avec 30 jours
      0[13-9]
      |
      1[012]
   )
   /
   (1[6-9]|[2-9]\d)\d{2} # Années comme ci-dessus

   |

   # Cas des mois avec 31 jours
   31
   /
   ( # Mois où le 31 est valide
      0[13578]
      |
      1[02]
   )
   /
   (1[6-9]|[2-9]\d)\d{2} # Années comme ci-dessus

   |

   # Cas du 29 février
   29/02/
   ( # Années
      (
         1[6-9] # 1600 à 1999
         |
         [2-9]\d # 2000 à 9999
      )
      ( # Les deux derniers chiffres sont divisibles par 4
         0[48]
         |
         [2468][048]
         |
         [13579][26]
      )
      |
      ( # Années valides finissant par un double zéro
         16
         |
         [2468][048]
         |
         [3579][26]
      )00
   )
)$

Conclusion :


Ça montre bien ce qu'il ne faut pas faire avec les expressions régulières ! En l'occurrence, écrire des expressions illisibles, trop complexes et difficilement maintenables...
D'un autre côté, cela montre aussi qu'avec un peu d'analyse et de structuration, on peut quand même comprendre de telles expressions.

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.