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

Collection et Stream Java Discussion :

Problème calcul de durée


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 86
    Par défaut Problème calcul de durée
    Bonjour,

    Je suis confronté à un problème qui semble tout à fait simple, mais que je n'arrive pas à résoudre, du moins simplement

    Je cherche à calculer, pour un évènement pouvant durer 24 heures (mais pouvant être à cheval sur deux jours civils), le temps passé durant une certaine plage horaire (pouvant être à cheval sur 2 jours) et qui se répète tous les jours.

    Par exemple :

    L'événement est une connexion définie par sa date de début et sa date de fin.
    La plage horaire de nuit est : 22h00 - 06h00
    -> comment calculer le temps passé de nuit de la connnexion ?

    piège : si la connexion dure de 05h00 jusqu'à 02h00 le lendemain, çà doit renvoyer 5 heures (1 heure au début et 4 à la fin)

    Je sais à peu près utiliser les Date / Calendar; c'est plus au niveau de l'algo que je patauge ... pourtant çà parait bête. Je dois l'être un peu aussi remarquez

    Merci de votre aide :-)

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    Parlons maths...

    Durée de la connexion : intervalle [A, B].
    Plages de nuit : union des intervalles [C+z, D+z] où z est un entier relatif et C < D.
    Je cherche l'ensemble des x appartenant à l'intersection de ces deux ensembles.

    Pour tout x dans l'intersection, il existe z entier tel que :
    A<x<B et C+z<x<D+z
    Alors :
    A<D+z et C+z<B
    Donc :
    A-D<z<B-C

    Soit [X, Y] un intervalle.
    Alors :
    [A, B] intersection [X, Y] = [max(A, X), min(B, Y)]

    J'en conclus que l'intersection de la connexion et des plages de nuit est l'union des [max(A, C+z), min(B, D+z)] pour z entier dans [A-D, B-C].

    Donc la durée que tu cherches est la somme des (min(B, D+z) - max(A, C+z)) pour z entier dans [A-D, B-C].

    Tadaaaaa
    Je te laisse comprendre (pas facile les maths sur un forum texte ) et adapter.

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    Petit ajout :

    Si tes plages étaient irrégulières au lieu de se répéter tous les jours (notons les [Cn, Dn]), on aurait :

    Connexion : [A, B]
    Plages : union sur n des [Cn, Dn]

    Intersection de la connexion et des plages :
    intersection de [A, B] et de (union sur n des [Cn, Dn])
    = union sur n des (intersection de [A, B] et de [Cn, Dn])
    = union sur n des [max(A, Cn), min(B, Dn)]

    Et donc durée commune :
    somme sur n des ((min(B, Dn) - max(A, Cn)) si la différence est positive)
    (si la différence est négative, l'intervalle est vide !)
    EDIT : à condition que les plages [Cn, Dn] ne se chevauchent pas


    Dans le cas de tes plages régulières, on a une infinité de plages mais on les connaît bien et donc on peut réduire le nombre d'éléments à sommer en calculant dans quel cas la différence sera négative (i.e. intervalle non vide) : c'est le calcul que j'ai effectué pour en déduire que les seuls z à prendre en compte dans le calcul sont les z dans [A/D, B/C].

  4. #4
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 86
    Par défaut
    Merci pour ta réponse Astartee... j'espère qu'elle ne va pas faire fuir les autres personnes qui pourraient m'aider

    En tous cas, belle démonstration mathématique : çà me rappelle ma jeunesse ! Ta formule :

    somme sur n des ((min(B, Dn) - max(A, Cn)) si la différence est positive)
    (si la différence est négative, l'intervalle est vide !)

    est très bien.

    Maintenant c'est au niveau de l'algo "Java" que çà me pose problème. Notament mes plages horaires qui sont plutôt du type [C + z*24h ; D + z*24h].

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    Citation Envoyé par absolut75 Voir le message
    Maintenant c'est au niveau de l'algo "Java" que çà me pose problème. Notament mes plages horaires qui sont plutôt du type [C + z*24h ; D + z*24h].
    Arf, oui, je me suis plantée dans mon premier post sur la forme des intervalles et ensuite, dans les calculs le nez dans le guidon !

    Mais en reprenant le deuxième post, ça t'indique quand même comment procéder
    Pour avoir une liste d'indices finie, donc exploitable, calcule les z qui te donneront des intervalles non vides...

  6. #6
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 86
    Par défaut
    Je tente çà si çà interesse quelqu'un (pas encore testé mais j'y crois):

    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
     
    static public long calcul(Date eventDebut, Date eventFin, int plageDebut, int plageFin) {
     
    		GregorianCalendar cal1 = new GregorianCalendar(); // debut plage
    		GregorianCalendar cal2 = new GregorianCalendar(); // fin plage
     
    		long intersection = 0;
     
    		// On définit la plage horaire qui commence avant debut
    		cal1.setTime(eventDebut);
    		cal1.set(Calendar.HOUR_OF_DAY, plageDebut);
    		cal1.set(Calendar.MINUTE, 0);
    		cal1.set(Calendar.SECOND, 0);
    		cal1.set(Calendar.MILLISECOND, 0);
    		if (cal1.getTime().after(eventDebut)) {
    			cal1.add(Calendar.DATE, -1);
    		}
     
    		cal2.setTime(cal1.getTime());
    		cal2.set(Calendar.HOUR_OF_DAY, plageFin);
    		if (cal2.getTime().before(cal1.getTime())) {
    			cal2.add(Calendar.DATE, 1);
    		}
     
    		// Tant que la plage horaire n'est pas postérieure à fin :
    		while (cal1.getTime().before(eventFin)) {
     
    			intersection += Math.max(Math.min(eventFin.getTime(), cal2.getTimeInMillis()) - Math.max(eventDebut.getTime(), cal1.getTimeInMillis()), 0);
     
    			// On décale la plage de 24h
    			cal1.add(Calendar.DATE, 1);
    			cal2.add(Calendar.DATE, 1);
     
    		}
     
    		return intersection;
    	}

    N'hésitez pas à me dire si vous trouvez plus simple ou mieux !

    Merci Astartee pour ton aide

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

Discussions similaires

  1. Problème de calcul de durée -MS project 2010-
    Par Nescencita dans le forum Project
    Réponses: 2
    Dernier message: 20/07/2011, 11h52
  2. Calculer la duree d'un MP3
    Par k-koo dans le forum C
    Réponses: 4
    Dernier message: 16/03/2006, 21h01
  3. Problème calculs js
    Par dogi dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 21/02/2006, 13h43
  4. [Date] Fonction de calcul de durée entre 2 dates
    Par jesus144 dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 10/01/2006, 16h36
  5. Calculer une duree entre 2 dates
    Par d.w.d dans le forum C++
    Réponses: 7
    Dernier message: 02/03/2005, 22h39

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