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

JavaScript Discussion :

Calcul avec les dates


Sujet :

JavaScript

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 54
    Par défaut Calcul avec les dates
    Bonjour à tous,

    Je suis face à un problème lors de calcul avec les dates sur une appli. A mon avis la solution ne doit pas être très compliquée mais j'ai beau chercher et je n'arrive pas à trouver.

    j'ai un fichier PHP appelé en ajax qui me renvoi le json suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [{"idDemande":"798","dateDebut":"2014-10-24","dateFin":"2014-10-30","miJourneeDeb":"0","miJourneeFin":"0"}]
    j’exécute ensuite le code javascript suivant :
    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
    nbjourspris=CalculCongePris(response, dateDebutPeriode, dateFinPeriode); //response est la réponse de la requete ajax soit mon json
     
     
    function CalculCongePris(response, dateDebCP, dateFinCP) {
            var nbjoursCPpris = 0;
            $.each(response, function(key, val) {
     
     
                datedeb = new Date(val.dateDebut);
                datef = new Date(val.dateFin);
                if (val.miJourneeDeb==1)
                {
                    nbjoursCPpris=nbjoursCPpris-0.5;
                }
                if (val.miJourneeFin==1)
                {
                    nbjoursCPpris=nbjoursCPpris-0.5;
                }
     
     
                while (datedeb <= datef) {
     
                    var weekoupas = isWeekend(datedeb);
                    var ferieoupas = isFeries(datedeb, dateFinCP.getFullYear());
     
                    plusgrandquedateDebP = datedeb > dateDebCP;
                    pluspetitquedateFinp = datedeb < dateFinCP;
    console.log(datedeb); // pour debug
                    //Vérifie la période
                    if (plusgrandquedateDebP && pluspetitquedateFinp) {
                        //Vérifie si ce n'est pas un weekend ni un jours férié
                        if (!weekoupas && !ferieoupas) {
                            nbjoursCPpris++;
                        }
                    }
                    datedeb.setDate(datedeb.getDate() + 1);
     
     
                }
            })
            return nbjoursCPpris;
        }
    Mon json contient une liste de période (demandes de congés)
    Ainsi, je devrais récupérer le nombre de jours de congés pris compris entre dateDebutPeriode et dateFinPeriode sachant qu'on enlève les jours fériées et les week end.
    Le problème est que j'ai une erreur sur le résultat lorsque j'ai dans mon json une période dans laquelle il y a eu un changement d'heure (passage à l'heure d'hiver par exemple). le problème se pose sur le contenu du json présenté plus haut.

    J'ai donc pu identifier que le problème apparait lorsqu'il y a un changement d'heure.
    le console.log que j'ai mis dans ma fonction me fait apparaitre qu'il y a un changement du fuseau horaire. Voici ci-dessous ce qui s'affiche dans la console :
    Date {Fri Oct 24 2014 02:00:00 GMT+0200}
    Date {Sat Oct 25 2014 02:00:00 GMT+0200}
    Date {Sun Oct 26 2014 02:00:00 GMT+0100}
    Date {Mon Oct 27 2014 02:00:00 GMT+0100}
    Date {Tue Oct 28 2014 02:00:00 GMT+0100}
    Date {Wed Oct 29 2014 02:00:00 GMT+0100}

    On voit donc que l'on passe de GMT+2 à GMT+1 au cours du traitement.

    Quelqu'un aurait-il une idée pour corriger ce problème ?

    PS : j'espère avoir été assez clair et avoir donné assez de détails mais n'hésitez pas à poser des questions

  2. #2
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    une date comme '2014-10-24' n'a pas de sens elle ne represente rien si tu ne spécifie pas le fuseau horaire et la façon dont tu le note.

    plutôt que new Date je te conseille d'utiliser Date.parse.
    et de fournir ta date au format ISO8601
    YYYY-MM-DDThh:mm:ssTZD => 1997-07-16T19:20:30+01:00

    quant à la façon de noter l'heure par rapport au fuseau
    2014-10-24T00:00:00+01:00
    et
    2014-10-24T00:00:00Z+01:00
    ne signifie pas la même chose le premier siginfie 0h00 dans le fuseau +01:00
    le second signifie qu'on est dans le fuseau +01:00 mais qu'il est 0h00 à greenwich (cette notation n'est quasiment jamais utilisée)

    C'est à mon avis toujours une mauvaise idée que d'exprimer une date sans préciser.
    le lecteur extrapole enfonction de ce qu'il peut et ça ne fonctionne quasiment jamais.

    imagine deux utilisateur de ton appli à tokyo et new york le new Date va tenir cmpte de leur horloge locale respective. '2014-10-24' n'aura pas le même sens pour tout les deux.

    A+JYT

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 54
    Par défaut
    Tout d'abord, merci pour ta réponse rapide.

    J'avai essayé de changer les lignes 9 et 10 comme suit afin de préciser le fuseau horaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    datedeb = new Date(val.dateDebut+"T00:00:00+01:00");
    datef = new Date(val.dateFin+"T00:00:00+01:00");
    mais sans résultat.


    Pour ce qui est d'utiliser Date.parse, il va falloir que j'étudie un peu plus le truc car je ne vois pas trop comment l'utiliser dans mon code....

  4. #4
    Membre chevronné
    Profil pro
    à la bougie alors
    Inscrit en
    Mai 2006
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : à la bougie alors

    Informations forums :
    Inscription : Mai 2006
    Messages : 224
    Par défaut
    Ton problème est lié au changement d'heure mais pas seulement. L'explication est dans l'affichage des dates :

    Date {Fri Oct 24 2014 02:00:00 GMT+0200}
    Date {Sat Oct 25 2014 02:00:00 GMT+0200}
    Date {Sun Oct 26 2014 02:00:00 GMT+0100}
    Date {Mon Oct 27 2014 02:00:00 GMT+0100}
    Date {Tue Oct 28 2014 02:00:00 GMT+0100}
    Date {Wed Oct 29 2014 02:00:00 GMT+0100}

    Dès la première ligne, il y a un problème :

    C'est bien le "2014-10-24" mais à 2h du matin. C'est à dire qu'il a compris dans new Date("2014-10-24") la date au fuseau horaire GMT+0000 et l'a convertie en fuseau horaire GMT+0200 (pourquoi ? mystère ... mais c'est trés implémentation dépendant et, dans certains environnements, la date est tout simplement invalide.)

    Date {Fri Oct 24 2014 00:00:00 GMT+0000} est devenue Date {Fri Oct 24 2014 02:00:00 GMT+0200}.

    Idem pour la date de fin (que tu n'affiches pas) en tenant compte du changement d'heure :

    Date {Thu Oct 30 2014 00:00:00 GMT+0000} est devenue Date {Thu Oct 30 2014 01:00:00 GMT+0100}.

    Soit le "2014-10-30" à 1h du matin (pas 2h). Donc lors de la dernière incrémentation, qui ne change pas l'heure comme tu peux le voir sur l'affichage des dates, il ne prend pas en compte le dernier jour car :

    Date {Thu Oct 30 2014 02:00:00 GMT+0100} == datedeb
    Date {Thu Oct 30 2014 01:00:00 GMT+0100} == datef
    le test while (datedeb <= datef) échoue, tu n'as pas ton dernier jour.

    Avec ton code existant, une solution primitive qui peut fonctionner :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function parseAsDate ( strdate ) {
      var dateComponents = strdate.split("-");
      return new Date(
          Number(dateComponents[0]),
          Number(dateComponents[1])-1,
          Number(dateComponents[2]) );
    }
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    datedeb = parseAsDate(val.dateDebut);
    datef   = parseAsDate(val.dateFin);
    les dates sont créées en temps local à minuit : datedeb == Date {Fri Oct 24 2014 00:00:00 GMT+0200} et datef == Date {Thu Oct 30 2014 00:00:00 GMT+0100}, la dernière itération donne :

    Date {Thu Oct 30 2014 00:00:00 GMT+0100} == datedeb
    Date {Thu Oct 30 2014 00:00:00 GMT+0100} == datef
    le test while (datedeb <= datef) réussit, tu as ton dernier jour.

    les limites de la solution : ton format de date doit correspondre avec celui attendu par 'parseAsDate' (pas de controles comme tu peux le voir).

    Mais le plus important est :
    Citation Envoyé par sekaijin Voir le message
    une date comme '2014-10-24' n'a pas de sens elle ne represente rien si tu ne spécifie pas le fuseau horaire
    Ce qui implique de revoir tes autres fonctions : 'isWeekend', 'isFerie'; tes arguments : 'dateDebCP', 'dateFinCP' pour coordonner tout ça.

    A ta place, sans connaitre tes contraintes, et en voulant limiter la taille de stockage : je conserverais mes dates en UTC+0000 (coté serveur) et j'irais regarder du coté de 'Date.UTC', 'Date.prototype.getUTC...', etc.

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 54
    Par défaut
    Merci bien pour cette solution "primitive".
    Cela m'a permis de corriger rapidement le bug pour que mes utilisateurs puissent travailler sereinement.
    Il me reste maintenant à paufiner tout ça pour que ce soit plus propre.

    Encore merci pour vos réponses

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 02/07/2014, 15h28
  2. [AC-2007] calcul avec les dates
    Par kasrimus dans le forum VBA Access
    Réponses: 9
    Dernier message: 01/09/2012, 14h47
  3. [CR XI] Calcule la durée du mois avec les date en cheval
    Par SophieTaureau dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 28/06/2012, 15h08
  4. Help!! Probleme avec les dates sur SQL SERVER
    Par Nadaa dans le forum MS SQL Server
    Réponses: 16
    Dernier message: 03/08/2006, 16h55
  5. [C#] Calcul sur les dates avec des DateTimePicker
    Par alizee971 dans le forum Windows Forms
    Réponses: 10
    Dernier message: 02/04/2005, 17h14

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