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.
17 févr. 2011 à 11:03
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...
16 févr. 2011 à 22:45
Un exemple nous permettrait néanmoins de progresser dès maintenant !
16 févr. 2011 à 22:04
<?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.
16 févr. 2011 à 21:17
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.
16 févr. 2011 à 20:11
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 !
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.