Partage
  • Partager sur Facebook
  • Partager sur Twitter

Calcul d'une durée comprise dans un intervalle

Fonction js calcul d'une durée comprise dans un intervalle

    29 novembre 2021 à 21:42:32

    Bonjour à tous

    Je cherche à écrire une fonction JS qui prend en compte 4 paramètres (heure d'arrivée, de départ, début de l'intervalle, fin de l'intervalle).

    Le but est de calculer le temps de travail de nuit d'une personne, par rapport à ses heures de présence. Pouvez-vous me dire si vous avez une solution ? J'ai déjà écrit un algorithme (je présente le code) mais j'ai des erreurs (parfois +1, parfois -1 par rapport à l'attendu).

    Par exemple, si l'intervalle (de nuit) est 21h00 - 07h00:

    Arrivée à 20h00, départ à 07h00, alors cela fait 10h de nuit

    Arrivée à 21h00, départ à 07h00, donc 10h

    Arrivée à 00h00, départ à 05h30, donc 05h30

    Arrivée à 07h00, départ à 21h00, alors 00h

    Résultat obtenus:

    20h - 08h00, attendu 10h00, j'ai 10h01

    21h - 07h00, attendu 10h00, j'ai 10h00 ok

    20h59 - 07h01, attendu 10h00, j'ai 10h01

    21h00 - 06h00, attendu 09h00, j'ai 09h00 ok

    20h59 - 23h59, attendu 02h59, j'ai 03h00

    06h00 - 22h00, attendu 02h00, j'ai 02h00 ok

    08h00 - 20h00, attendu 00h00, j'ai 00h00 ok

    Voici mon code:

    // Variables
    arrival
    departure
    lower
    higher
    	
    var res=0;
    
    // Je crée des "rangs" d'heures
    var rangeHours = [];
    if (arrival < departure) rangeHours = [{from:arrival, to:departure}];
    else rangeHours = [{from:arrival, to:24*60}, {from:0, to:departure}]
    
    // J'exclue les horaires qui ne font pas parti de l'intervalle
    var excludeHours = [];
    // Ex: Si poste de jour de 06h00 à 21h00, j'exclue de 00h00 à 06h00, et 21h01 à 24h00
    if (lower < higher) {
    	excludeHours.push( {from:-1, to:lower} );
    	excludeHours.push( {from:higher+1, to:24*60} );
    }
    // Si poste de nuit de 21h00 à 06h00, j'exclue de 6 à 21
    else if (lower > higher) {
    	excludeHours.push( {from:higher+1,to:lower-1} );
    }
    	
    
    var finalHours = rangeHours;
    if (excludeHours.length) {
    	finalHours = excludeRange(rangeHours, [excludeHours[0]]);
    	for (var i=1; i<excludeHours.length; i++) {
    		finalHours = excludeRange(finalHours, [excludeHours[i]]);
    	}
    }
    	
    // Je somme les intervalles restants
    for (range in finalHours) {
    	if (finalHours[range].from > -1 && finalHours[range].to > -1)
    		res += Math.abs(finalHours[range].to - finalHours[range].from);
    }
    	
    return res;
    
    
    
    
    /**
     *
     */
    function excludeRange(include, exclude) {
    	var resultList = [];
    
         for (var i=0;i<include.length;i++){
    
             var inc = include[i];
             var overlap = false;
    
             for (var x=0;x<exclude.length;x++ ){
    
                 var exc = exclude[x];
    
                 //4 scenarios to handle
    
                 if (exc.from >= inc.from && exc.to <= inc.to){
                     //include swallows exclude - break in two
                     resultList.push({from: inc.from, to: exc.from - 1});
                     resultList.push({from: exc.to + 1, to: inc.to});
                     overlap = true;
                 }else if (exc.from <= inc.from && exc.to >= inc.to){
                     //exclude swallows include - exclude entire range
                     overlap = true;
                     break;
                 }else if (exc.from <= inc.from && exc.to <= inc.to && exc.to >= inc.from){
                     //exclusion overlaps on left
                     resultList.push({from: exc.to, to: inc.to});
                     overlap = true;
                 }else if (exc.from >= inc.from && exc.to >= inc.to && exc.from <= inc.to){
                     //exclusion overlaps on right
                     resultList.push({from: inc.from, to: exc.from - 1});
                     overlap = true;
                 }
    
             }
    
             if (!overlap){
                 //no exclusion ranges touch the inclusion range
                 resultList.push(inc);
             }
         }
    
    	return resultList;
    
    }
    
    
    
    
    



    • Partager sur Facebook
    • Partager sur Twitter
      30 novembre 2021 à 12:42:32

      Salut,

      voilà ce que je te propose :

      let arrivee = 7.20;//en heures et minutes
      let depart = 9.54;
      //si on a des décimales, on les convertit sur une base 100 au lieu de 60
      if (!Number.isInteger(depart)) depart = convert(depart);
      if (!Number.isInteger(arrivee)) arrivee = convert(arrivee);
      
      function convert(num){
        //on change les minutes sur une base de 100, et non de 60 minutes
        // 7h10 minutes -> 7.17 sur une base 100
        let n = (num+"").match(/(\d*)\.?(\d{1,2})/);//les parenthèses () permettent de capturer les groupes, n[1] sera le 1er groupe, n[2] le 2e groupe, entre les deux, il y a un point
        if (n[2].length == 1) n[2] += "0"; //il y a un bug quand c'est 10, ça donnait 1 au lieu de 10, donc on rajoute 0 à la main si besoin
        
        let int = n[1];
        let dec = parseFloat(n[2]) / 60;//on fait un pourcentage pour la base 100
        let total = parseInt(int) + parseFloat(dec.toFixed(2));//on change les "string" en number pour additionner, sinon ça se colle l'un à côté de l'autre
        console.log("total : "+total);
        return total;
      }
       
      
      let heures = calc(7, 10, arrivee, depart);//donc pour l'intervalle 7h 10h, la personne arrive à 7h20 et repart à 9h54
      console.log(heures);//le résultat des minutes est en base 100 
      
      function calc(intDebut, intFin, arrivee, depart){ //intDebut = intervalle de début
        if (arrivee < intDebut) arrivee = intDebut;
        if (depart > intFin) depart = intFin;
      
        let heures = depart-arrivee;//si c'est 7h / 21h;
        if (intFin < intDebut) { //si c'est 21h - 7h, de nuit, 7 < 21
          heures = 24 - depart + arrivee;
        }
        return heures.toFixed(2);//2 chiffres après la virgules
      }



      -
      Edité par Arthur222 30 novembre 2021 à 22:41:06

      • Partager sur Facebook
      • Partager sur Twitter

      Calcul d'une durée comprise dans un intervalle

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown