Javascript : Vérifiez la validité d’une date en raisonnant par l’absurde !

Vérifier la validité d’une date est une tâche souvent laborieuse. Voici une méthode innovante qui va vous permettre de le faire rapidement sans compter le nombre de jours pour un mois donné et sans avoir besoin de vérifier si une année est bissextile.

Si vous faites du développement web de manière régulière et que vous vous êtes essayé au Javascript, vous avez certainement déjà eu l’occasion de réaliser quelques scripts de contrôle de premier niveau sur la saisie des champs dans un formulaire html.

Parmi les différents contrôles que vous pouvez être amenés à faire sur des champs de saisie, il se peut que vous ayiez à réaliser un contrôle sur la validité d’une date. A partir de là, deux solutions s’offrent à vous :
- soit vous récupérez un script sur le net et vous l’appliquez tel quel à votre cas.
- soit vous vous plongez dans la programmation à partir de zéro et vous vous rendrez vite compte qu’il va falloir y passer plus de temps que vous ne le croyiez.

Dans les deux cas, vous verrez certainement que pour contrôler la validité d’une date, vous êtes obligé de passer par une analyse syntaxique, puis de vérifier si l’année et bissextile, de créer une fonction qui retourne le nombre de jours dans un mois, etc…
Bref, plus vous allez écrire de fonctions, plus le risque d’erreur augmente.

Cette façon de procéder reste cependant bien souvent la seule possible pour la plupart des langages de programmation.
Mais pas pour le JavaScript. En effet, en ce qui concerne la manipulation d’une date, JavaScript apporte une tolérance.
Aussi, quelle n’a pas été ma surprise lorsqu’en demandant à JavaScript de me construire la date du 32 janvier 2001, il me répondit 1er février 2001 !!
En effet, là où je m’attendais à déclencher une erreur comme l’auraient fait probablement bon nombre de langages, JavaScript calcule une date correcte équivalente !
Il en est de même si je fais 0 janvier 2001, j’obtiens 31 décembre 2000 sous Internet Explorer, 1er janvier 2001 sous Netscape.
Et bien utilisons donc ce comportement inattendu en notre faveur, et qu’à cela ne tienne si je n’obtiens pas toujours la même chose sous Netscape ou Internet Explorer : raisonnons désormais par l’absurde !

Principe de l’algorithme de vérification de la validité d’une date.

L’utilisateur saisit une date quelconque. On la récupère sous forme de chaîne, passage obligé, on l’analyse pour en obtenir les jour, mois, année renseignés.
Il ne reste plus qu’à demander à JavaScript de construire l’objet Date correspondant. Si j’obtiens alors le même jour, le même mois et la même année, c’est que la date était valide !

Et c’est tout. J’ai terminé ma vérification, pas besoin de fonction retournant le nombre de jours dans un mois ou qui vérifie si une année est bissextile…

function isDateValid(chaineDate) {

\\ Je regarde tout d'abord si la chaîne n'est pas vide, 
\\ sinon pas la peine d'aller plus loin
   if (chaineDate != "") return false

\\ J'utilise split pour créer un tableau dans lequel je récupère les jour mois année
\\ J'attends bien sûr une date formatée en JJ/MM/AAAA
   var ladate = (chaineDate).split("/")

\\ Si je n'ai pas récupéré trois éléments ou bien s'il ne s'agit pas 
\\ d'entiers, pas la peine non plus d'aller plus loin
   if ((ladate.length != 3) || isNaN(parseInt(ladate[0])) || 
     isNaN(parseInt(ladate[1])) || isNaN(parseInt(ladate[2]))) 
        return false

\\ Sinon, c'est maintenant que je crée la date correspondante. 
\\ Attention, les mois sont étalonnés de 0 à 11
   var unedate = new Date(eval(ladate[2]),eval(ladate[1])-1,eval(ladate[0]))

\\ Bug de l'an 2000 oblige, lorsque je récupère l'année, 
\\ je n'ai pas toujours 4 chiffres selon les navigateurs, je rectifie donc ici le tir.
   var annee = unedate.getYear()
   if ((Math.abs(annee)+"").length < 4) annee = annee + 1900

\\ Il ne reste plus qu'à vérifier si le jour, le mois et l'année 
\\ obtenus sont les mêmes que ceux saisis par l'utilisateur.
   return ((unedate.getDate() == eval(ladate[0])) && 
        (unedate.getMonth() == eval(ladate[1])-1) && 
        (annee == eval(ladate[2])))
}