Calcul du nombre de jours contenus dans l'intersection de deux périodes

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 558 fois - Téléchargée 15 fois

Contenu du snippet

Cette fonction calcul le nombre de jours contenus dans la période issue de l'intersection de deux périodes, c'est à dire le nombre de jour appartenant à la fois aux deux périodes.

Source / Exemple :


/************************************************************

  • Calcul le nombre de jour contenu dans la période d'intersection
  • entre deux périodes (Nombre de jour appartenant aux deux périodes)
  • $d1 string : Date de début période 1 (format YYYY-MM-DD)
  • $f1 string : Date de fin de la période 1
  • $d2 string : Date de début période 2
  • $f2 string : Date de fin période 2
  • Retour interger : Nombre de jour appartenant aux deux périodes.
                                                                                                                                          • /
function nbJourIntersection ($d1, $f1, $d2, $f2) { if ( ($d1 >= $d2 && $d1 <= $f2) || ($f1 >= $d2 && $f1 <= $f2) || ($d2 >= $d1 && $d2 <= $f1)) { //*** Il y a intesction entre les deux periodes if ($d1 >= $d2 && $f1 <= $f2) { //*** CAS n°1 : periode 1 est inclue dans perdiode 2 $di = $d1; $fi = $f1; } else if ($d1 <= $d2 && $f1 >= $f2) { //*** CAS n°2 : periode 2 est inclue dans perdiode 1 $di = $d2; $fi = $f2; } else if ($d2 >= $d1 && $d2 <= $f1) { //*** CAS n°3 : periode 1 à cheval à gauche sur perdiode 2 $di = $d2; $fi = $f1; } else { //*** CAS n°4 : periode 1 à cheval à droite sur perdiode 2 $di = $d1; $fi = $f2; } // Calcul le nombre de jour sur la periode d'intersection $arr_di = explode ('-', $di); $arr_fi = explode ('-', $fi); $time_di = mktime (0, 0, 0, $arr_di[1], $arr_di[2], $arr_di[0]); $time_fi = mktime (0, 0, 0, $arr_fi[1], $arr_fi[2], $arr_fi[0]); $nbJour = round((($time_fi - $time_di) / 60 / 60 / 24)) + 1; return $nbJour; } else { //*** Il n'y a pas intersection entre les deux periodes return 0; } } // nbJourIntersection

Conclusion :


Exemple :
$nbJour = nbJourIntersection ('2011-01-02', '2011-01-10', '2011-01-08', '2011-01-20');

$nbJour contient la valeur 3.

A voir également

Ajouter un commentaire

Commentaires

Messages postés
279
Date d'inscription
mercredi 22 septembre 2010
Statut
Membre
Dernière intervention
8 janvier 2014
3
Merci pour ce morceau de code dont chacun pourra apprécier la lisibilité. Pour ma part, je crains que la grammaire des chaînes de caractères proposée (voir le new DateTime) ait quelques difficultés à s'imposer... À moins qu'elle préfigure la reconnaissance vocale ?

Et puis, un exemple de configuration, considérée à tort par l'auteur comme sans intersection, conforterait là encore des affirmations quelques peu péremptoires...
Messages postés
279
Date d'inscription
mercredi 22 septembre 2010
Statut
Membre
Dernière intervention
8 janvier 2014
3
Encore une fois, nous n'avons rien à faire des changements d'heures pour traiter cette question ! Pour le reste, précisons simplement que mktime reste parfaitement pertinent de 1901 à 2038, ce qui nous laisse quelques délais pour aborder ces fameuses classes...

Un exemple nous permettrait néanmoins de progresser dès maintenant !
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
15
Juste pour l'aspect didactique :
<?php

function daysIntersection($from1, $to1, $from2, $to2) {
if ($to1 >= $from2 && $to2 >= $from1) { // Intersection des deux périodes
$from = new DateTime(max($from1, $from2));
$to = new DateTime(min($to1, $to2) . ' +1day'); // On ajoute 1 jour, car PHP ne travaille pas sur des journées pleines, mais de minuit à minuit.
$interval = $from -> diff($to);
return $interval -> format('%a');
}
return 0; // Pas d'intersection des deux périodes
}

date_default_timezone_set('Europe/Paris');
echo daysIntersection('2011-01-02', '2011-01-10', '2011-01-08', '2011-01-20');

?>

Notez :
- le test d'intersection simplifié (plus juste aussi, car en tout, il y a 6 cas, l'auteur de la source n'en traite que 5, considérant à tort une configuration comme sans intersection)
- la lisibilité du code (plus facile à comprendre quand on découvre le code)
- la possibilité de formater la période grâce à DateInteval::format() (cf : http://fr.php.net/manual/fr/dateinterval.format.php )

Maintenant, je conçois parfaitement que chacun préfère continuer d'utiliser des méthodes de développement obsolètes et refusent les outils "modernes". Simplement, le code que je présente nécessite PHP5.2, qui est installé même chez Free et OVH, c'est dire si on peut considérer que cette version est la minimum à prendre en compte quand on développe aujourd'hui en PHP. Oubliez un peu le procédural et optimisez votre code, vous verrez, ça fait beaucoup de bien.
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
15
C'est vrai, mktime sait utiliser le changement d'heure été/hiver. Il faut passer le 7ème paramètre, celui qui est justement omis dans la source.
Mais comme ce paramètre est obsolète depuis PHP 5.1, il faut utiliser le gestionnaire de fuseau horaire à la place, exactement comme cette source ne le fait pas. Ce qui provoquerait très certainement une erreur de type E_STRICT sur mon serveur.

Je me suis donc mal exprimé : cette source qui utilise mktime, ne prend pas en compte le changement d'heure été/hiver.

Là où je me suis mal exprimé également, c'est sur le fait que cette source, qui se contente de compter les jours en divisant le temps obtenu en secondes par 86400 ne donne pas un résultat pertinent.

Bref : je persiste à dire que les classes DateTime et DateInterval fournissent un résultat bien plus pertinent et avec beaucoup moins de lignes de code... Mais comme cela relèguerait la classe au statut de snippet, on admettra que cette source puisse servir d'exemple pour ce qu'il ne faut pas faire.
Messages postés
279
Date d'inscription
mercredi 22 septembre 2010
Statut
Membre
Dernière intervention
8 janvier 2014
3
Qu'est-ce que c'est que ces sornettes ?
D'abord, le calcul peut consister à inverser les périodes ou a considérer le début et la fin d'une même période si celle-ci est incluse dans l'autre.
Ensuite, depuis quand mktime ne prend plus en compte les années bissextiles ?
Pour clore le tout, le changement d'heure n'intervient pas lorsque l'on travaille seulement sur les dates à 0 heures 0 minutes 0 secondes !
Afficher les 10 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.