Aller au contenu
David Vincent

Vérifiez une date en raisonnant par l'absurde !

Recommended Posts

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.

Lisez l'article intégral sur les publications du Hub

Faites-moi un petit coucou pour me dire si cette astuce vous a été utile ;)

Partager ce message


Lien à poster
Partager sur d’autres sites
Dan    133

Salut David,

Impressionnant ! Tu ne serais pas tenté par de la publication Spip ?

Je pense que ton article mérite d'y être déplacé ;)

Dan

<edit: c'est maintenant chose faite !>

Partager ce message


Lien à poster
Partager sur d’autres sites
MrFab    0

perso, j'évite les contrôles en js, il y a de trop nombreux utilisateurs qui le désactivent. Je m'en remets au php. Et sans contrôle, ça donne parfois des bases de données complètement trouées de partout : /

Au moins côté serveur, on est sûr de ne pas avoir de mauvaises surprises.

Ce qui n'enlève rien à la qualité de ton article, mon cher David :D

Modifié par MrFab

Partager ce message


Lien à poster
Partager sur d’autres sites

Oui, je découvre SPIP depuis quelques heures et j'avoue que je cafouille un peu :)

J'ai reposté cet article dans SPIP, j'espère ne pas provoquer trop de soucis.

Et pour répondre à MrFab, oui, tu as raison, il est indispensable de faire systématiquement les contrôles côté serveur. C'est effectivement la seule partie que tu maîtrises vraiment.

Ce n'est par contre pas le cas du navigateur client. Faire ses contrôles côté client uniquement n'est pas suffisant car le JavaScript peut-être désactivé.

L'utilité de faire des contrôles côté client existe pourtant bien, si JavaScript est activé, il permet d'éviter des aller / retour inutiles vers le serveur, ce qui permet d'alléger sa charge de travail (surtout s'il s'agit d'un site très fréquenté) et de faire gagner du temps à l'internaute.

Mais répétons-le, les contrôles côté serveur restent indispensables :)

Modifié par David Vincent

Partager ce message


Lien à poster
Partager sur d’autres sites
Dan    133
Oui, je découvre SPIP depuis quelques heures et j'avoue que je cafouille un peu :)

J'ai reposté cet article dans SPIP, j'espère ne pas provoquer trop de soucis.

Tu t'es débrouillé comme un chef!

Spip est un CMS très rapide à appréhender, tu viens d'en faire une éclatante démontration ;)

Dan

PS: J'ai édité ton post pour y mettre le lien vers l'article sous Spip. C'est mieux car Spip se référence infiniment mieux que n'importe quel forum.

Googlebot a digéré toute la partie publication cet après midi. ;)

Dan

Partager ce message


Lien à poster
Partager sur d’autres sites
Anonymus    0

petit coucou ;)

pour dire que l'info sera probablement bientot utile.

Je suis également du style à faire tout ca en php, mais c'est vrai que décharger une partie de la tache au javascript, ce peut etre une bonne alternative.

A+, Anonymus

Partager ce message


Lien à poster
Partager sur d’autres sites
Anonymus    0

Donc, en php, je propose :

<?

$date="03/9/2003";

$valide_date=explode("/",$date);

if (checkdate($valide_date[1],$valide_date[0],$valide_date[2])){

echo"date valide : <br>";

}

?>

Ca ne vérifie pas si la date est correcte, mais à mon avis, ca vérifie si elle est bonne. La différence ? La doc dit :

L'année est comprise entre entre 1 et 32767 inclus.

Voilà, A+, Anonymus.

Partager ce message


Lien à poster
Partager sur d’autres sites
Jan    1

Ex-cel-lent script! Comme quoi on n'a jamais fait complètement le tour de javascript :rolleyes:

Si rien ne remplace effectivement la vérif coté serveur, j'essaye pour ma part de le soulager au maximum (le pôvre petit):

- pour les vérifications de formulaires, je place dans le formulaire à vérifier un champ caché (hidden), disons jsactif, dont la "value" par défaut est false.

- Lors de la soumission du formulaire, j'appelle un script javascript qui fait la vérif des champs du formulaire ET positionne jsactif à true

- après envoi au serveur, je teste coté serveur la valeur du champ jsactif

- s'il est false (le script javascript au onSubmit n'a pas été exécuté, donc javascript est désactivé), je fais la vérif coté serveur

- s'il est true (le script javascript au onSubmit a été exécuté, donc javascript est activé), je n'ai pas besoin de faire la vérif coté serveur: tout bénef...

C'est avec les petits ruisseaux qu'on fait les grandes rivières :whistling:

Partager ce message


Lien à poster
Partager sur d’autres sites
phplive    0

Bjr

Oui ... mais

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

serait plus juste comme ca :

if (chaineDate == "") return false

:D

Partager ce message


Lien à poster
Partager sur d’autres sites
silvain59    0

géniale l'idée !!!!

Mais juste une petite rectification de tordu !!! Ca vérifie bien si le jour,mois, année sont des entiers avec isNaN donc exclu les cas ou un caractère autre qu'un chiffre est entré.

Mais il y a une petite correction à rajouter: Si pour le jour,le mois ou l'année on rentre un "." à la fin comme 2./5./200. aucune erreur n'est renvoyée !! Car le parseInt renvoie pour le jour "2" qui est bien un nombre... Donc il faut faire un petit test pour etre sur qu'il n'y a pas un "." a la fin du jour, du mois et de l'année

voici le test complet que j'utilise:

if ((ladate.length != 3) || isNaN(ladate[0]) || isNaN(ladate[1]) || isNaN(ladate[2]) || eval(ladate[0])<0 || eval(ladate[1])<0 || eval(ladate[2])<0 || parseInt(ladate[0])!=parseFloat(ladate[0]) || parseInt(ladate[1])!=parseFloat(ladate[1]) || parseInt(ladate[2])!=parseFloat(ladate[2]) || ladate[0].substr(ladate[0].length-1,1)=="." || ladate[1].substr(ladate[1].length-1,1)=="." || ladate[2].substr(ladate[2].length-1,1)==".") return false

explications:

il faut naturellement tester que les entrées soit positives car isNaN(-1) renvoie true (c'est bel est bien un nombre un relatif !)

ensuite il faut tester que parseInt soit egal a parseFloat car exemple:

parseInt(.5) = 5

parseFloat(.5) = 0.5

on elimine donc par ce test le cas ou l'utilisateur rentre un floatant comme année par exemple

le test du "." a la fin est toujours necessaire car

parseInt(5.) = 5

parseFloat(5.) = 5

voila c'est un peu compliqué mais c'est histoire d'avoir une liste exhaustive des differentes eventualités et histoire d'etre sur que la date est CORRECTE a 100% !!

mais ca n'enleve rien a ton génie !

silvain

Modifié par silvain59

Partager ce message


Lien à poster
Partager sur d’autres sites
romsiw    0

En gros, ma question : cette fonction ne fait que vérifier ? (booléen ?)

Modifié par romsiw

Partager ce message


Lien à poster
Partager sur d’autres sites
romsiw    0

Bon excusez le post précédent, c'est du n'importe quoi :(

Voici le test que j'ai fait :

j'ai cette date entrée dans le champs : 23/07/2004

onblur="if(doverif_valid_date(this.value)) alert('ok'); else alert('pas ok');"

et il me met pas ok onblur du champs... ??

Partager ce message


Lien à poster
Partager sur d’autres sites
silvain59    0

Oui cette fonction ne fait que vérifier.

Je te redis vite fait le principe pour que tu t'en rendes compte:

Javascript corrige automatiquement des dates incorrects et renvoie une valeur qui lui parait correcte.

Ainsi si tu tape 0 janvier 2001 comme date, soit si tu es sous IE il te retourne 31 decembre 2000, soit si tu es sous Netscape 2 janvier 2001. D'ou le 1er pb, si tes utilisateurs ont des navigateurs différents (ce qui est fort probable) la correction automatique ne sera pas la meme !

Et puis le 2e pb (nettement plus genant) si l'utilisateur tape une date au format completement merdique: sans le mois ou avec des lettres... comment veux-tu que la fonction puisse te corriger ca en une date cohérente proche de celle que l'utilisateur aura voulu rentrer ?!!! L'ère de l'IA approche mais tout de meme :1eye:

silvain

Partager ce message


Lien à poster
Partager sur d’autres sites
silvain59    0

j'ai essayé et je pense que tout simplement il te faut utiliser des { }:

onblur="if(doverif_valid_date(this.value)) {alert('ok');} else {alert('pas ok');}"

dis moi si ca marche ;)

silvain

Partager ce message


Lien à poster
Partager sur d’autres sites

Ce sont les expressions régulières.

J'avoue ne pas être très fort là dedans, c'est un très grand tort d'ailleurs.

Ca permet un travail sur les chaines de caractères très précis et performant.

Pour le php le site qui fait référence (en français en tous cas) est http://www.expreg.com.

Pour le javascript une recherche sur google peut être pratique :)

Partager ce message


Lien à poster
Partager sur d’autres sites

Absoluement, ma fonction peut être simplifiée au niveau de la vérification syntaxique grâce à une expression régulière. Je ne connaissais pas à l'époque et c'est pour ça que je n'en ai pas mis.

Celle-ci devrait faire l'affaire :

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 une expression régulière pour normaliser ma date en "JJ/MM/AAAA"

// au cas où la date aurait été saisie au format "JJ-MM-AAAA" ou "JJ.MM.AAAA".

chaineDate = chaineDate.replace(/(-|\.)/g, "/")

// Je teste ensuite si la date contient des entiers.

// Le jour et le mois inférieurs à 10 peuvent être écrits sans le zéro.

// L'année doit être sur 4 chiffres.

if (chaineDate.search(/^[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{4}$/) == -1) return false

// On crée un tableau dans lequel on récupère les jour mois année

var ladate = chaineDate.match(/\d{2,4}/g)

// Maintenant on 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])))

}

Ah, c'est quand-même dur de s'y mettre aux expressions, régulières, mais ça rend bien des services quand-même.

Modifié par David Vincent

Partager ce message


Lien à poster
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant

×