130 votes

Calculer le nombre d'heures entre 2 dates en PHP

Comment calculer la différence entre deux dates en heures ?

Par exemple :

day1=2006-04-12 12:30:00
day2=2006-04-14 11:30:00

Dans ce cas, le résultat devrait être de 47 heures.

1 votes

Ma première réponse aurait été de transformer les deux valeurs en horodatage en utilisant la fonction strftime() et diviser la différence par 3600, mais cela fonctionnera-t-il toujours ? Maudite soit l'heure d'été !

1 votes

@Pekka : non, ça ne marchera pas toujours, je suppose... Jetez un coup d'oeil à ma réponse. J'y ai posté une solution prenant en compte les fuseaux horaires, les années bissextiles, les secondes intercalaires et les dst :)

0 votes

@Pekka, si vous utilisez strtotime() cela fonctionnera toujours, pour autant que vous utilisiez le fuseau horaire par défaut OU que vous spécifiez explicitement le décalage du fuseau horaire. Aucune raison de maudire le DST.

253voto

faileN Points 2746

Les versions plus récentes de PHP fournissent de nouvelles classes appelées DateTime , DateInterval , DateTimeZone et DatePeriod . L'avantage de cette classe est qu'elle prend en compte les différents fuseaux horaires, les années bissextiles, les secondes intercalaires, l'heure d'été, etc. Et en plus de cela, elle est très facile à utiliser. Voici ce que vous voulez avec l'aide de ces objets :

// Create two new DateTime-objects...
$date1 = new DateTime('2006-04-12T12:30:00');
$date2 = new DateTime('2006-04-14T11:30:00');

// The diff-methods returns a new DateInterval-object...
$diff = $date2->diff($date1);

// Call the format method on the DateInterval-object
echo $diff->format('%a Day and %h hours');

L'objet DateInterval, qui est retourné, fournit aussi d'autres méthodes que format . Si vous souhaitez obtenir le résultat en heures uniquement, vous pouvez procéder comme suit :

$date1 = new DateTime('2006-04-12T12:30:00');
$date2 = new DateTime('2006-04-14T11:30:00');

$diff = $date2->diff($date1);

$hours = $diff->h;
$hours = $hours + ($diff->days*24);

echo $hours;

Et voici les liens pour la documentation :

Toutes ces classes offrent également une manière procédurale/fonctionnelle d'opérer avec les dates. Jetez donc un coup d'œil à l'aperçu : http://php.net/manual/book.datetime.php

0 votes

+1 Bon travail ! Cela semble solide et constitue une bonne vue d'ensemble. Il est important de noter que les calculs peuvent varier selon le fuseau horaire en raison des différentes règles DST, donc c'est probablement une bonne idée de toujours définir la zone et de ne pas se fier aux paramètres du serveur.

0 votes

Oui. Avec cet objet, vous pouvez même calculer des dates dans des fuseaux horaires différents. $date1 = new DateTime('2006-04-12T12:30:00 Europe/Berlin'); et $date2 = new DateTime('2006-04-14T11:30:00 America/New_York');

7 votes

Si quelqu'un rencontre le même problème que moi où $diff->d est égal à 0 (parce que j'essaie de calculer les heures entre deux dates qui ont exactement 2 mois d'écart) : En cours d'exécution var_dump($diff) m'a montré un autre paramètre : ["days"]=>int(61) J'ai donc fini par utiliser $hours = $diff->days * 24; et le résultat est proche de la "moyenne" de 1440 heures pour 2 mois de 30 jours, ce qui est bien mieux qu'un résultat de 0 (je suppose que ma version de PHP est un peu ancienne...).

91voto

Jan Hančič Points 19496
$t1 = strtotime( '2006-04-14 11:30:00' );
$t2 = strtotime( '2006-04-12 12:30:00' );
$diff = $t1 - $t2;
$hours = $diff / ( 60 * 60 );

7 votes

Pourquoi pas ? $diff / 3600 ?

10 votes

@AlexG C'est juste une question de style. Même résultat, mais les programmeurs utilisent généralement la multiplication lorsqu'il s'agit de temps.

0 votes

Je vous suggère d'utiliser : round(($t1 - $22) / 3600) ; utiliser l'arrondi pour obtenir les heures correctes.

18voto

Sergey Eremin Points 6237

Votre réponse est :

round((strtotime($day2) - strtotime($day1))/(60*60))

6 votes

Et s'il y a 2 heures et 30 minutes d'intervalle ? Votre réponse donnera 3 heures. Je pense qu'il serait préférable d'utiliser le plancher, ce qui donnerait 2 heures. Mais cela dépend vraiment de la situation.

17voto

Walter Tross Points 3559

Le moyen le plus simple d'obtenir le nombre correct d'heures entre deux dates (datetimes), même en cas de changement d'heure d'été, est d'utiliser la différence entre les timestamps Unix. Les horodatages Unix sont des secondes écoulées depuis 1970-01-01T00:00:00 UTC, sans tenir compte des secondes intercalaires (c'est bien parce que vous n'avez probablement pas besoin de cette précision, et parce qu'il est assez difficile de prendre en compte les secondes intercalaires).

La manière la plus flexible de convertir une chaîne de date avec des informations facultatives sur le fuseau horaire en un horodatage Unix est de construire un fichier de type DateTime (éventuellement avec un DateTimeZone en tant que second argument dans le constructeur), et ensuite appeler son getTimestamp méthode.

$str1 = '2006-04-12 12:30:00'; 
$str2 = '2006-04-14 11:30:00';
$tz1 = new DateTimeZone('Pacific/Apia');
$tz2 = $tz1;
$d1 = new DateTime($str1, $tz1); // tz is optional,
$d2 = new DateTime($str2, $tz2); // and ignored if str contains tz offset
$delta_h = ($d2->getTimestamp() - $d1->getTimestamp()) / 3600;
if ($rounded_result) {
   $delta_h = round ($delta_h);
} else if ($truncated_result) {
   $delta_h = intval($delta_h);
}
echo "h: $delta_h\n";

1 votes

D'après un commentaire dans le manuel il apparaît que, pour la compatibilité avec les dates pré-époques, format("U") est préférable à getTimestamp()

1 votes

@Arth, je ne sais pas quand c'était le cas, mais dans mon PHP 5.5.9, ce n'est plus vrai. getTimestamp() renvoie maintenant exactement la même valeur que format("U") . Le premier est un entier, alors que le second est une chaîne de caractères (moins efficace ici).

0 votes

Cool, peut-être que c'était vrai dans une version antérieure Oui un entier serait plus propre, donc je préférerais getTimestamp() si je pouvais en être sûr.

4voto

Hoàng Vũ Tgtt Points 71
//Calculate number of hours between pass and now
$dayinpass = "2013-06-23 05:09:12";
$today = time();
$dayinpass= strtotime($dayinpass);
echo round(abs($today-$dayinpass)/60/60);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X