IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contributions JavaScript / AJAX Discussion :

Comment vérifier si un champ qui contient la date et l'heure au format [Fait]


Sujet :

Contributions JavaScript / AJAX

  1. #1
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 142
    Points
    11 142
    Par défaut Comment vérifier si un champ qui contient la date et l'heure au format
    http://javascript.developpez.com/faq...erifFormatDate

    • Je remplace les appels à eval() par un parseInt(nombre, 10);. Je précise la base 10 car parseInt() va considérer que si la chaine de caractère débute par un 0, la valeur est en base 8.
      J'ai donc remanié le code en ce sens.
    • La fonction traite les dates au format américain c'est à dire yyyy-mm-dd hh:mm:ss. Je propose en plus une fonction qui traite les dates au format jj-mm-aaaa hh:mm:ss
    • La fonction date.getYear() retourne, selon le navigateur, une année sur 2 ou 4 chiffres. Je l'ai remplacée par getFullYear(), plus fiable à mon avis. Du coup, le test if (an.length<4) an=an+1900; devient inutile.
    • J'ai également aéré le code en ajoutant des lignes vides
    • Mise à jour 18/11 : groupement des déclarations de variables



    Voici ma proposition de correction :
    Pour analyser une date au format "yyyy-mm-dd hh:mm:ss" (format américain) :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    // date au format yyyy-mm-dd hh:mm:ss
    function IsGoodDate(mydate)
    {
    	var thedate, year, month, day;
    	var onedate;
    	var thetime, hours, minutes, seconds;
    	var onetime;
     
    	var mysplit=mydate.split(' ');
    	if (mysplit.length != 2) 
    		return false;
     
    	thedate=mysplit[0].split('-');
    	year = parseInt(thedate[0],10);
    	month = parseInt(thedate[1],10);
    	day = parseInt(thedate[2],10);
     
     
    	if ((mysplit[0].length != 10) || (thedate.length != 3) ||
    		(isNaN(year)) || (isNaN(month)) || (isNaN(day)) ||
    		(thedate[0].length < 4) || (thedate[1].length < 2) || (thedate[2].length < 2)) 
    			return false;
     
    	onedate = new Date(year, month-1, day);
    	year = onedate.getFullYear();
     
    	if ((onedate.getDate() != day) ||
    		(onedate.getMonth() != month-1) ||
    		(onedate.getFullYear() != year )) 
    			return false;
     
     
    	thetime = mysplit[1].split(':');
    	hours = parseInt(thetime[0],10);
    	minutes = parseInt(thetime[1],10);
    	seconds = parseInt(thetime[2],10);
     
    	if ((mysplit[1].length != 8) || (thetime.length != 3)||
    		(isNaN(hours)) || (isNaN(minutes)) || (isNaN(seconds)) ||
    		(thetime[0].length < 2) || (thetime[1].length < 2) || (thetime[2].length < 2)) 
    			return false;
     
    	onetime = new Date(year, month-1, day, hours, minutes, seconds);
     
    	if ((onetime.getHours() != hours) || (onetime.getMinutes() != minutes) || (onetime.getSeconds() != seconds))
    		return false;
     
    	return true;
    }
    Cette fonction teste d'abord si le paramètre "mydate" est bien composé des 2 éléments date et heure séparés par un espace. Ensuite, on teste si la date est bien composée des 3 éléments séparés par des tirets et si les longueurs de ces éléments sont bien 4, 2 et 2. Après ça, la fonction vérifie la validité de la date en la testant directement dans le calendrier (concordance)... Par exemple, 2004-02-31 retournera false car il n'existe pas de 31 février... Pour l'heure, c'est un peu pareil...


    Pour analyser une date au format "jj-mm-aaaa hh:mm:ss" (format français) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    // date au format dd-mm-yyyy hh:mm:ss
    function IsGoodDate(mydate)
    {
    	var thedate, day, month, year;
    	var onedate;
    	var thetime, hours, minutes, seconds;
    	var onetime;
     
    	var mysplit=mydate.split(' ');
    	if (mysplit.length != 2) 
    		return false;
     
    	thedate=mysplit[0].split('-');
    	day = parseInt(thedate[0],10);	
    	month = parseInt(thedate[1],10);	
    	year = parseInt(thedate[2],10);
     
    	if ((mysplit[0].length != 10) || (thedate.length != 3) ||
    		(isNaN(year)) || (isNaN(month)) || (isNaN(day)) ||
    		(thedate[0].length < 2) || (thedate[1].length < 2) || (thedate[2].length < 4)) 
    			return false;
     
    	onedate = new Date(year, month-1, day);
    	year = onedate.getFullYear();
     
    	if ((onedate.getDate() != day) ||
    		(onedate.getMonth() != month-1) ||
    		(onedate.getFullYear() != year )) 
    			return false;
     
    	thetime = mysplit[1].split(':');
    	hours = parseInt(thetime[0],10);
    	minutes = parseInt(thetime[1],10);
    	seconds = parseInt(thetime[2],10);
     
    	if ((mysplit[1].length != 8) || (thetime.length != 3)||
    		(isNaN(hours)) || (isNaN(minutes)) || (isNaN(seconds)) ||
    		(thetime[0].length < 2) || (thetime[1].length < 2) || (thetime[2].length < 2)) 
    			return false;
     
    	onetime = new Date(year, month-1, day, hours, minutes, seconds);
     
    	if ((onetime.getHours() != hours) || (onetime.getMinutes() != minutes) || (onetime.getSeconds() != seconds))
    		return false;
     
    	return true;
    }


  2. #2
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Citation Envoyé par Auteur
    [*] La fonction date.getYear() retourne, selon le navigateur, une année sur 2 ou 4 chiffres. Je l'ai remplacée par getFullYear(), plus fiable à mon avis. Du coup, le test if (an.length<4) an=an+1900; devient inutile.
    La méthode getYear() a été conservée pour des raisons de rétrocompatibilité mais ne devrait plus être utilisée.

    Pour l'ensemble :
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  3. #3
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 142
    Points
    11 142
    Par défaut
    Citation Envoyé par Bovino Voir le message
    La méthode getYear() a été conservée pour des raisons de rétrocompatibilité mais ne devrait plus être utilisée.
    Tu proposes de la laisser finalement ?

    Citation Envoyé par Bovino Voir le message
    Pour l'ensemble :
    Merci




    Proposition d'amélioration du script : j'ai combiné les deux fonctions.
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    // date au format dd-mm-yyyy hh:mm:ss (fr)
    // date au format yyyy-mm-dd hh:mm:ss (en)
    function IsGoodDate(mydate, format)
    {
    	var thedate, day, month, year;
    	var onedate;
    	var thetime, hours, minutes, seconds;
    	var onetime;	
     
    	var mysplit=mydate.split(' ');
     
    	if (mysplit.length != 2) 
    		return false;
     
    	thedate=mysplit[0].split('-');
     
    	if (format=="en")
    	{
    		year = parseInt(thedate[0],10);
    		month = parseInt(thedate[1],10);
    		day = parseInt(thedate[2],10);
     
    		if ((mysplit[0].length != 10) || (thedate.length != 3) ||
    			(isNaN(year)) || (isNaN(month)) || (isNaN(day)) ||
    			(thedate[0].length < 4) || (thedate[1].length < 2) || (thedate[2].length < 2)) 
    				return false;	
    	}
    	else if (format=="fr")
    	{
    		day = parseInt(thedate[0],10);	
    		month = parseInt(thedate[1],10);	
    		year = parseInt(thedate[2],10);
     
    		if ((mysplit[0].length != 10) || (thedate.length != 3) ||
    			(isNaN(year)) || (isNaN(month)) || (isNaN(day)) ||
    			(thedate[0].length < 2) || (thedate[1].length < 2) || (thedate[2].length < 4)) 
    				return false;
    	}
    	else 
    		return false;
     
    	onedate = new Date(year, month-1, day);
    	year = onedate.getFullYear();
     
    	if ((onedate.getDate() != day) ||
    		(onedate.getMonth() != month-1) ||
    		(onedate.getFullYear() != year )) 
    			return false;
     
    	thetime = mysplit[1].split(':');
    	hours = parseInt(thetime[0],10);
    	minutes = parseInt(thetime[1],10);
    	seconds = parseInt(thetime[2],10);
     
    	if ((mysplit[1].length != 8) || (thetime.length != 3)||
    		(isNaN(hours)) || (isNaN(minutes)) || (isNaN(seconds)) ||
    		(thetime[0].length < 2) || (thetime[1].length < 2) || (thetime[2].length < 2)) 
    			return false;
     
    	onetime = new Date(year, month-1, day, hours, minutes, seconds);
     
    	if ((onetime.getHours() != hours) || (onetime.getMinutes() != minutes) || (onetime.getSeconds() != seconds))
    		return false;
     
    	return true;
    }

    La fonction prend un paramètre supplémentaire qui s'appelle format. Sa valeur est soit "fr" soit "en".

    IsGoodDate("18-11-2012 11:36:00", "fr"); retournera true
    IsGoodDate("18-11-2012 11:36:00", "en"); retournera false

    IsGoodDate("2012-11-18 11:36:00", "fr"); retournera false
    IsGoodDate("2012-11-18 11:36:00", "en"); retournera true

    Dans le cas où le second paramètre est ni "fr" ni "en" la fonction retournera false.
    Tout ceci sous réserve que la chaine passée contienne effectivement une date et une heure valides.
    Par contre pour comparer deux chaines de caractères c'est bien cette syntaxe if (format=="en") ? J'ai comme un doute

  4. #4
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Non non, je disais juste que cette méthode fait encore partie de JavaScript pour des raisons de rétrocompatibilité mais qu'elle est obsolète et ne doit pas être utilisée, donc tu as eu raison de la remplacer !
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  5. #5
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 142
    Points
    11 142
    Par défaut
    J'ai corrigé les scripts pour prendre en compte la remarque de Daniel

    Je vous demande donc une nouvelle relecture et vos avis.


  6. #6
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Alors à titre personnel, je n'aime pas trop les if, else et autres sans accolades, mais je suis peut-être trop maniaque...
    D'autre part, un nom de fonction commençant par une majuscule est habituellement (c'est une convention) à un constructeur, ce qui n'est pas le cas ici.
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  7. #7
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Citation Envoyé par Auteur
    Par contre pour comparer deux chaines de caractères c'est bien cette syntaxe if (format=="en") ? J'ai comme un doute
    Oui, oui, c'est bien ça
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  8. #8
    Expert éminent sénior

    Avatar de vermine
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    6 582
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 6 582
    Points : 79 912
    Points
    79 912
    Par défaut
    Effectivement, les novices sont déjà vite perturbés donc si la syntaxe prend des raccourcis, on risque d'en perdre plus d'un en chemin.

  9. #9
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 142
    Points
    11 142
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Alors à titre personnel, je n'aime pas trop les if, else et autres sans accolades, mais je suis peut-être trop maniaque...
    Citation Envoyé par vermine Voir le message
    Effectivement, les novices sont déjà vite perturbés donc si la syntaxe prend des raccourcis, on risque d'en perdre plus d'un en chemin.
    J'ai mis des accolades dans mes if else Sauf s'il y une ligne d'instruction dans la condition, naturellement. Cela pose un souci ?
    A moins que vous ne préfériez avoir deux fonctions distinctes ?

    Citation Envoyé par Bovino Voir le message
    D'autre part, un nom de fonction commençant par une majuscule est habituellement (c'est une convention) à un constructeur, ce qui n'est pas le cas ici.
    je mettrai une minuscule dans ce cas

  10. #10
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Sauf s'il y une ligne d'instruction dans la condition, naturellement.
    Justement, c'est là-dessus que je ne suis pas "d'accord".
    Enfin, c'est une des mes conventions de codage... mais perso, je mets toujours des accolades. Ensuite, ta syntaxe étant correcte, à toi de voir ce que tu préfères : je le redis, c'est juste une remarque personnelle.
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  11. #11
    Expert éminent sénior

    Avatar de vermine
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    6 582
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 6 582
    Points : 79 912
    Points
    79 912
    Par défaut
    Je l'avoue, j'ai déjà sorti un truc du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    while(...)
       if(...)
          for(...)
             if(...)
                if(...)
                   instruction ;
    Ce n'est pas cool pour les suivants.

  12. #12
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 142
    Points
    11 142
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Justement, c'est là-dessus que je ne suis pas "d'accord".
    Enfin, c'est une des mes conventions de codage... mais perso, je mets toujours des accolades. Ensuite, ta syntaxe étant correcte, à toi de voir ce que tu préfères : je le redis, c'est juste une remarque personnelle.
    Citation Envoyé par vermine Voir le message
    Je l'avoue, j'ai déjà sorti un truc du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    while(...)
       if(...)
          for(...)
             if(...)
                if(...)
                   instruction ;
    Ce n'est pas cool pour les suivants.
    C'est hors sujet mais je vous donne ma convention :

    S'il y a 1 instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (condition)
       instruction
    else
       instruction
    // saut de ligne
    instruction
    Dans ce cas, je trouve que les accolades alourdissent le code inutilement. Mais je prends la peine d'ajouter une ligne vide à la fin de la condition pour séparer les blocs.


    Plusieurs instructions, je mets les accolades (de toutes façons c'est obligatoire ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if (condition)
    {
        instruction1
        instruction2
    }
    else
      instruction

    Ensuite pour reprendre le cas posé par Vermine, je m'impose les accolades, sauf peut-être pour le dernier if :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    while(...)
    {
       if(...)
       {
          for(...)
          {
             if(...)
             {
                if(...)
                   instruction
             } 
          }
       }
    }
    Je m'impose également le retour à la ligne pour les accolades ouvrantes et fermantes, la syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       if(...) {
          instruction1
          instruction2
      }
    m'énerve car je recherche toujours les accolades ouvrantes

  13. #13
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Bonjour,
    <toujours_hors_sujet>
    et pourquoi ne pas utiliser un outil tel que Online JavaScript beautifier pour la mise en forme finale même si ce n'est pas lui qui va écrire/ajouter les accolades ou autres point virgule...
    </toujours_hors_sujet>

  14. #14
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 183
    Points : 274
    Points
    274
    Par défaut
    Bonjour,


    Je suis souvent très étonné de la longueur des fonctions de validation de date, on se retrouve souvent, soit avec une fonction qui reproduit le calcul du calendrier gregorien, soit une fonction qui utilise Date (c'est un mieux) mais qui fait 10km de long.

    Je vous propose une solution plus barbare mais qui permet de réduire les fonctions de validation de date à leur minimum.

    Premièrement, la fonction de validation de date au strict minimum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function dateValidate(y, m, d) {
        d=new Date(y, m-1, d);
        return d.getMonth() == m-1 && d.getFullYear()==y;
    };
    Comment ça marche, ben c'est très simple, on lui fourni un y, m, d pour annee, mois, jours en paramètre, et on créé une date, et ensuite on reteste les valeurs fournies en entrées pour quelles matchent bien avec celles de la date créée.
    Attention le mois rentré dans cette fonction va de 1 à 12.

    Alors évidement ça ne gère pas les heures/minutes/secondes, mais on peut y remédier très facilement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    function dateValidate(y,m,d,h,n,s) {
        /*
        on fixe les valeurs par défaut si elles ne sont pas rentrées, 
        donc h,n,s sont facultatifs
        */
     
      h=h||0;n=n||0;s=s||0; 
     
        /*on passe par un with pour eviter la creation d'une
        nouvelle date et alléger l'écriture*/
     
     
        with(new Date(y, m-1, d, h,n,s)) 
        /* pas besoin de tester secondes, car si on met 61 secondes, 
           minutes nous sortira un false dans ce cas.
         */
        return getMonth() == m-1 && getFullYear()==y && getDate()==d && getHours()==h && getMinutes()==n; 
    };
    Voila c'est joliiiiiii


    Maintenant reste à gérer cette histoire de masque, je vous propose une solution assez warrior, mais qui marche à merveille.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    function dateValidateFromMask(str, mask) {
        //Valide la date pour savoir si elle respecte le mask
        if(!new RegExp(mask.replace(/[ymdhns]/gi,'\\d').replace(/\//g,'\\/')).test(str)) return false;
     
        // valide la date au niveau des valeurs y/m/d/h/n/s
        var dateArr = str.split(/\D+/),
            values = {};
     
        /* créé un objet qui associera les y/m/d du mask avec la date pour 
          ensuite les reutiliser la fonction dateValidate.
          si str = "2012/23/05" et mask = "YYYY/DD/MM";
         values = {y:"2012", m:"05", d:"23"};
        */
        mask.match(/([ymdhns]+)/gi).forEach(function(str,i) {
          values[str.charAt(0).toLowerCase()] = dateArr[i];
        });
        return dateValidate(values.y, values.m, values.d, values.h, values.n, values.s);
    }

    dateValidateFromMask("2012/31/12","YYYY/DD/MM"); => true;
    dateValidateFromMask("2012/31/12","YYYY/MM/DD"); => false;
    dateValidateFromMask("03/25/1998","MM/DD/YYYY"); => true;
    dateValidateFromMask("03/25/1998","mm/dd/yyyy"); => true;
    dateValidateFromMask('25/12/2010 - 12:54:32', 'dd/mm/yyyy - hh:nn:ss'); => true


    Si je vire les commentaires des fonctions ça nous donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    function dateValidate(y,m,d,h,n,s) {
      h=h||0;n=n||0;s=s||0; 
        with(new Date(y, m-1, d, h,n,s)) 
        return getMonth() == m-1 && getFullYear()==y && getDate()==d && getHours()==h && getMinutes()==n; 
    };
     
    function dateValidateFromMask(str, mask) {
        if(!new RegExp(mask.replace(/[ymdhns]/gi,'\\d').replace(/\//g,'\\/')).test(str)) return false;
        var dateArr = str.split(/\D+/),
            values = {};
        mask.match(/([ymdhns]+)/gi).forEach(function(str,i) {
          values[str.charAt(0).toLowerCase()] = dateArr[i];
        });
        return dateValidate(values.y, values.m, values.d, values.h, values.n, values.s);
    }
    Et oui 15 petites lignes mais qui font de grandes choses
    On peut même reproduire le principe de "fr" ou "en" pour rationaliser les mask avec une simple ligne de code et en se basant sur un objet de masks
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var masks = {
      "fr": "dd-mm-yyyy hh:nn:ss",
      "en": "mm-dd-yyyy hh:nn:ss"
    }
    Et dans la fonction dateValidateFromMask() il suffirait juste d'écrire en première ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    mask = masks[mask] || mask;
    Après ya plus qu'à mettre tout ça dans un petit objet et rulez

    Je vous laisse méditer la dessus et j'aime le travail que vous faites


    edit : Pour fini on met tout dans un objet. Vous pouvez réutiliser ça dans vos projets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    var DateValidator = {
        validate: function (y, m, d, h, n, s) {
            h = h || 0;
            n = n || 0;
            s = s || 0;
            with(new Date(y, m - 1, d, h, n, s))
            return getMonth() == m - 1 && getFullYear() == y && getDate() == d && getHours() == h && getMinutes() == n;
        },
     
        validateFromMask: function (str, mask) {
            mask = this.mask[mask]*|| mask;
            if (!new RegExp(mask.replace(/[ymdhns]/gi, '\\d').replace(/\//g, '\\/')).test(str)) return false;
            var dateArr = str.split(/\D+/),
                arr = mask.match(/([ymdhns]+)/gi),
                values = {};
            for (var i = 0; i < arr.length; i++) {
                values[arr[i].charAt(0).toLowerCase()] = dateArr[i];
            }
            return this.validate(values.y, values.m, values.d, values.h, values.n, values.s);
        },
     
        mask: {
            "fr": "dd-mm-yyyy hh:nn:ss",
            "en": "mm-dd-yyyy hh:nn:ss"
        }
    };
     
    console.log(DateValidator.validateFromMask("04-24-2003 12:34:52", "en"));

  15. #15
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 183
    Points : 274
    Points
    274
    Par défaut
    Citation Envoyé par vermine Voir le message
    Je l'avoue, j'ai déjà sorti un truc du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    while(...)
       if(...)
          for(...)
             if(...)
                if(...)
                   instruction ;
    Ce n'est pas cool pour les suivants.
    Je reste un peu dans le hors sujet, mais si tu commences à avoir 2 boucles imbriquées, essaye de créer une fonction par boucle, ça allègera ton code et facilitera la compréhension.
    Et une autre règle d'or : une fonction ne doit faire qu'une seule chose, pas 36

  16. #16
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Pas sûr que l'utilisation des with soit pertinente.

    Peut être spécifier également que forEach n'est pas encore complétement crossBrowser.

    Comme on est dans une FAQ il me semble important de laisser les commentaires, explications, sous une forme ou une autre.

  17. #17
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 183
    Points : 274
    Points
    274
    Par défaut
    Citation Envoyé par NoSmoking Voir le message
    Pas sûr que l'utilisation des with soit pertinente.

    Peut être spécifier également que forEach n'est pas encore complétement crossBrowser.

    Comme on est dans une FAQ il me semble important de laisser les commentaires, explications, sous une forme ou une autre.
    La dernière version ne comporte pas de forEach, Le with, même s'il n'est pas réellement indiqué, sert ici pour gagner en octets, cela m'évite d'avoir à écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    var date = new Date(y,m,d...);
    return date.getFullYear()==y && date.getMonth()==m-1 .....
    Je réécricrais un peu plus proprement pour que ce soit developpez.net compliant dès que j'aurais un moment. A noter que je suis entrain d'écrire une librairie de manipulation de dates extra light, même si moment.js et date.js existe, le mien ne sera utile que pour 90% des cas de manipulation de date rencontrés

  18. #18
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 142
    Points
    11 142
    Par défaut
    Je regarderai plus en détail vos différentes contributions.

    Mais il y a d'ores et déjà un détail qui me chagrine dans les codes de Arnogues : c'est l'utilisation des expressions régulières. Si un débutant voit ces fonctions il va être dérouté sans parler du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        mask.match(/([ymdhns]+)/gi).forEach(function(str,i) {
          values[str.charAt(0).toLowerCase()] = dateArr[i];
        });
    qui risque de carrément rebuter un débutant

    Je pense que même si les codes proposés par Arnogues sont intéressants (je ne les ai pas testés, j'avoue ) ils sont néanmoins destinés à un public assez aguerri. Il ne faut pas oublier que la FAQ est plutôt destinée, dans une certaine mesure, à un public plutôt novice, d'autant plus que la gestion de la date et l'heure fait partie, à mes yeux, des bases javascript.

    Peut-être que l'on peut les ajouter dans la FAQ mais avec un avertissement ou un tag [Confirmé] comme on peut le voir dans certains tutoriels, ou alors les placer dans la partie "scripts utiles".
    Qu'en pensez-vous ?

  19. #19
    Membre actif

    Profil pro
    Inscrit en
    Juillet 2012
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 183
    Points : 274
    Points
    274
    Par défaut
    Citation Envoyé par Auteur Voir le message
    Je regarderai plus en détail vos différentes contributions.

    Mais il y a d'ores et déjà un détail qui me chagrine dans les codes de Arnogues : c'est l'utilisation des expressions régulières. Si un débutant voit ces fonctions il va être dérouté sans parler du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        mask.match(/([ymdhns]+)/gi).forEach(function(str,i) {
          values[str.charAt(0).toLowerCase()] = dateArr[i];
        });
    qui risque de carrément rebuter un débutant

    Je pense que même si les codes proposés par Arnogues sont intéressants (je ne les ai pas testés, j'avoue ) ils sont néanmoins destinés à un public assez aguerri. Il ne faut pas oublier que la FAQ est plutôt destinée, dans une certaine mesure, à un public plutôt novice, d'autant plus que la gestion de la date et l'heure fait partie, à mes yeux, des bases javascript.

    Peut-être que l'on peut les ajouter dans la FAQ mais avec un avertissement ou un tag [Confirmé] comme on peut le voir dans certains tutoriels, ou alors les placer dans la partie "scripts utiles".
    Qu'en pensez-vous ?
    Plus ou moins d'accord, il suffit de simplifier mon code, par exemple, je n'utilise plus de foreach dans le tout dernier morceau de code, il y a juste à rajouter des commentaires

    Il faut savoir que le code n'a pas forcément de niveau, il est là à un instant T destiné à rendre service. En principe un débutant va aller utiliser jquery sans savoir comment c'est codé derrière, ben ici c'est un peu le même principe.

    Quand on regarde le code que tu as pondu, il est quand même plus compliqué à comprendre que le mien, car il manipule les strings dans tous les sens. Le mien est très simple à comprendre :

    - Tu as un masque :yyyy/mm/dd
    - Tu as une date : 2012/04/20
    - Via mon code j'associe chaque groupe de lettre du mask à chaque groupe de chiffre de la date :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    var values = {
       y : 2012,
       m : 4,
       d : 20
    }
    - A partir de là je récréé une date à partir des valeurs y, m et d, et compare ces valeurs avec ce que va me ressortir la date via getFullYear(), getMonth() et getDate().
    - Bien entendu je n'oublie pas que les moins vont de 0 à 11 en JS.

  20. #20
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 650
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 650
    Points : 11 142
    Points
    11 142
    Par défaut
    Comme je n'ai pas eu de remarques depuis plus d'un mois, on peut sans doute placer ce code dans la FAQ :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    // date au format dd-mm-yyyy hh:mm:ss (fr)
    // date au format yyyy-mm-dd hh:mm:ss (en)
    function isGoodDate(mydate, format)
    {
    	var thedate, day, month, year;
    	var onedate;
    	var thetime, hours, minutes, seconds;
    	var onetime;	
     
    	var mysplit=mydate.split(' ');
     
    	if (mysplit.length != 2) 
    	{	
    		return false;
    	}
     
    	thedate=mysplit[0].split('-');
     
    	if (format=="en")
    	{
    		year = parseInt(thedate[0],10);
    		month = parseInt(thedate[1],10);
    		day = parseInt(thedate[2],10);
     
    		if ((mysplit[0].length != 10) || (thedate.length != 3) ||
    			(isNaN(year)) || (isNaN(month)) || (isNaN(day)) ||
    			(thedate[0].length < 4) || (thedate[1].length < 2) || (thedate[2].length < 2)) 
    		{
    				return false;	
    		}
    	}
    	else if (format=="fr")
    	{
    		day = parseInt(thedate[0],10);	
    		month = parseInt(thedate[1],10);	
    		year = parseInt(thedate[2],10);
     
    		if ((mysplit[0].length != 10) || (thedate.length != 3) ||
    			(isNaN(year)) || (isNaN(month)) || (isNaN(day)) ||
    			(thedate[0].length < 2) || (thedate[1].length < 2) || (thedate[2].length < 4)) 
    		{
    			return false;
    		}			
    	}
    	else 
    	{	
    		return false;
    	}		
     
    	onedate = new Date(year, month-1, day);
    	year = onedate.getFullYear();
     
    	if ((onedate.getDate() != day) ||
    		(onedate.getMonth() != month-1) ||
    		(onedate.getFullYear() != year )) 
    	{		
    		return false;
    	}		
     
    	thetime = mysplit[1].split(':');
    	hours = parseInt(thetime[0],10);
    	minutes = parseInt(thetime[1],10);
    	seconds = parseInt(thetime[2],10);
     
    	if ((mysplit[1].length != 8) || (thetime.length != 3)||
    		(isNaN(hours)) || (isNaN(minutes)) || (isNaN(seconds)) ||
    		(thetime[0].length < 2) || (thetime[1].length < 2) || (thetime[2].length < 2)) 
    	{
    		return false;
    	}
     
    	onetime = new Date(year, month-1, day, hours, minutes, seconds);
     
    	if ((onetime.getHours() != hours) || (onetime.getMinutes() != minutes) || (onetime.getSeconds() != seconds))
    	{	
    		return false;
    	}		
     
    	return true;
    }


    La fonction prend un paramètre supplémentaire qui s'appelle format. Sa valeur est soit "fr" soit "en".

    IsGoodDate("18-11-2012 11:36:00", "fr"); retournera true
    IsGoodDate("18-11-2012 11:36:00", "en"); retournera false

    IsGoodDate("2012-11-18 11:36:00", "fr"); retournera false
    IsGoodDate("2012-11-18 11:36:00", "en"); retournera true

    Dans le cas où le second paramètre est ni "fr" ni "en" la fonction retournera false.
    Tout ceci sous réserve que la chaine passée contienne effectivement une date et une heure valides.

    Par rapport à ma dernière proposition j'ai simplement ajouté des accolades dans les conditions avec 1 instruction pour ne pas rebuter des débutants. Toujours dans ce même objectif, je n'ai pas pris en compte les propositions de Arnogues, trop compliquées pour un débutant à mes yeux :
    Citation Envoyé par Auteur
    Je pense que même si les codes proposés par Arnogues sont intéressants ils sont néanmoins destinés à un public assez aguerri. Il ne faut pas oublier que la FAQ est plutôt destinée, dans une certaine mesure, à un public plutôt novice, d'autant plus que la gestion de la date et l'heure fait partie, à mes yeux, des bases javascript.

Discussions similaires

  1. [AC-2007] Comment définir un champ qui contient un pdf ?
    Par juju05 dans le forum Access
    Réponses: 3
    Dernier message: 24/02/2015, 09h37
  2. Réponses: 4
    Dernier message: 20/01/2010, 15h04
  3. Vérifier un champs qui contient un tableau
    Par jeremygata dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 27/05/2008, 16h39
  4. Réponses: 2
    Dernier message: 20/01/2007, 11h19
  5. Réponses: 1
    Dernier message: 05/12/2005, 22h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo