web-dev-qa-db-fra.com

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.

87
Thinker

Les nouvelles versions de PHP fournissent de nouvelles classes appelées DateTime, DateInterval, DateTimeZone et DatePeriod. La bonne chose à propos de cette classe est qu’elle considère différents fuseaux horaires, années bissextiles, secondes bissextiles, été, etc. Et en plus, c’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 renvoyé, fournit également d'autres méthodes que format. Si vous voulez le résultat en heures seulement, vous pouvez faire quelque chose comme ceci:

$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 un moyen procédural/fonctionnel de fonctionner avec des dates. Par conséquent, jetez un coup d'œil à la vue d'ensemble: http://php.net/manual/book.datetime.php

175
Alex Sawallich
$t1 = StrToTime ( '2006-04-14 11:30:00' );
$t2 = StrToTime ( '2006-04-12 12:30:00' );
$diff = $t1 - $t2;
$hours = $diff / ( 60 * 60 );
61
Jan Hančič

Fournir une autre méthode pour DatePeriod

Il tient compte de l'heure d'été dans les fuseaux horaires applicables, sans qu'il soit nécessaire de calculer le nombre de secondes ou d'heures entre les dates.

Nombre d'heures _ ​​(par exemple: https://3v4l.org/Vom6N )

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

//determine what interval should be used - can change to weeks, months, etc
$interval = new \DateInterval('PT1H');

//create periods every hour between the two dates
$periods = new \DatePeriod($date1, $interval, $date2);

//count the number of objects within the periods
$hours = iterator_count($periods);
echo $hours . ' hours'; 

Résultat

47 hours

Compter le nombre d'heures avec l'heure avancée _ ​​(par exemple: https://3v4l.org/eO9KE )

//set timezone to UTC to disregard daylight savings
ini_set('date.timezone', 'America/New_York'); 
$date1 = new \DateTime('2006-01-01T12:00:00');
$date2 = new \DateTime('2006-06-01T12:00:00');
$interval = new \DateInterval('PT1H');

$periods = new \DatePeriod($date1, $interval, $date2);
$hours = iterator_count($periods);
echo $hours . ' hours';

Résultat

3623 hours

La même méthode peut être utilisée pour déterminer les périodes de paie et récupérer les dates au lieu de les compter.

Périodes de paie _ ​​(par exemple: https://3v4l.org/WQoh5 )

$interval = new \DateInterval('P2W');
$payPeriodStart = new \DateTime('2012-08-12T00:00:00');
$today = new \DateTime('2016-03-04T12:00:00');
$today->add($interval);
$payPeriods = new \DatePeriod($payPeriodStart, $interval, $today);
$payPeriods = array_reverse(iterator_to_array($payPeriods));

$recent = [
   'current' => [
       'start' => $payPeriods[1]->format('Y-m-d'),
       'end' => $payPeriods[0]->format('Y-m-d')
   ],
   'previous' => [
       'start' => $payPeriods[2]->format('Y-m-d'),
       'end' => $payPeriods[1]->format('Y-m-d')
   ]
];
var_dump($recent);

Résultat

array(2) {
  ["current"]=>
  array(2) {
    ["start"]=>
    string(10) "2016-02-21"
    ["end"]=>
    string(10) "2016-03-06"
  }
  ["previous"]=>
  array(2) {
    ["start"]=>
    string(10) "2016-02-07"
    ["end"]=>
    string(10) "2016-02-21"
  }
}
18
fyrye

votre réponse est:

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

16
Sergey Eremin

Le moyen le plus simple d’obtenir le nombre correct d’heures entre deux dates, même après les changements d’heure avancée, consiste à utiliser la différence entre les horodatages Unix. Les horodatages Unix sont des secondes écoulées depuis le 1970-01-01T00: 00: 00 UTC, en ignorant les secondes intercalaires (c'est correct car vous n'avez probablement pas besoin de cette précision et parce qu'il est assez difficile de prendre en compte les secondes intercalaires).

Le moyen le plus flexible de convertir une chaîne datetime avec des informations de fuseau horaire optionnelles en un horodatage Unix consiste à construire un objet DateTime (éventuellement avec un DateTimeZone comme second argument du constructeur), puis à 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";
12
Walter Tross
//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);
4
Hoàng Vũ Tgtt
$day1 = "2006-04-12 12:30:00"
$day1 = strtotime($day1);
$day2 = "2006-04-14 11:30:00"
$day2 = strtotime($day2);

$diffHours = round(($day2 - $day1) / 3600);

Je suppose que la fonction strtotime () accepte ce format de date.

3
Boris Delormas
<?
     $day1 = "2014-01-26 11:30:00";
     $day1 = strtotime($day1);
     $day2 = "2014-01-26 12:30:00";
     $day2 = strtotime($day2);

   $diffHours = round(($day2 - $day1) / 3600);

   echo $diffHours;

?>
3
Night Walker

Malheureusement, la solution fournie par FaileN ne fonctionne pas comme indiqué par Walter Tross .. les jours peuvent ne pas être 24 heures!

J'aime utiliser les objets PHP dans la mesure du possible et pour un peu plus de souplesse, j'ai développé la fonction suivante:

/**
 * @param DateTimeInterface $a
 * @param DateTimeInterface $b
 * @param bool              $absolute Should the interval be forced to be positive?
 * @param string            $cap The greatest time unit to allow
 *
 * @return DateInterval The difference as a time only interval
 */
function time_diff(DateTimeInterface $a, DateTimeInterface $b, $absolute=false, $cap='H'){

  // Get unix timestamps, note getTimeStamp() is limited
  $b_raw = intval($b->format("U"));
  $a_raw = intval($a->format("U"));

  // Initial Interval properties
  $h = 0;
  $m = 0;
  $invert = 0;

  // Is interval negative?
  if(!$absolute && $b_raw<$a_raw){
    $invert = 1;
  }

  // Working diff, reduced as larger time units are calculated
  $working = abs($b_raw-$a_raw);

  // If capped at hours, calc and remove hours, cap at minutes
  if($cap == 'H') {
    $h = intval($working/3600);
    $working -= $h * 3600;
    $cap = 'M';
  }

  // If capped at minutes, calc and remove minutes
  if($cap == 'M') {
    $m = intval($working/60);
    $working -= $m * 60;
  }

  // Seconds remain
  $s = $working;

  // Build interval and invert if necessary
  $interval = new DateInterval('PT'.$h.'H'.$m.'M'.$s.'S');
  $interval->invert=$invert;

  return $interval;
}

Cette fonction date_diff() crée une DateTimeInterval, mais avec l'unité la plus élevée exprimée en heures plutôt qu'en années .. elle peut être formatée comme d'habitude.

$interval = time_diff($date_a, $date_b);
echo $interval->format('%r%H'); // For hours (with sign)

N.B. J'ai utilisé format('U') au lieu de getTimestamp() en raison du commentaire dans le manual . Notez également que 64 bits sont requis pour les dates post-époque et pré-négatives!

2
Arth

Cela fonctionne dans mon projet. Je pense que cela vous sera utile.

Si Date est dans le passé, alors inverti sera 1.
Si la date est dans le futur, alors inverti sera 0.

$defaultDate = date('Y-m-d');   
$datetime1   = new DateTime('2013-03-10');  
$datetime2   = new DateTime($defaultDate);  
$interval    = $datetime1->diff($datetime2);  
$days        = $interval->format('%a');
$invert      = $interval->invert;
0
Gurudutt Sharma

Cette fonction vous aide à calculer les années et les mois exacts entre deux dates données, $doj1 et $doj. Il renvoie l'exemple 4.3 signifie 4 ans et 3 mois.

<?php
    function cal_exp($doj1)
    {
        $doj1=strtotime($doj1);
        $doj=date("m/d/Y",$doj1); //till date or any given date

        $now=date("m/d/Y");
        //$b=strtotime($b1);
        //echo $c=$b1-$a2;
        //echo date("Y-m-d H:i:s",$c);
        $year=date("Y");
        //$chk_leap=is_leapyear($year);

        //$year_diff=365.25;

        $x=explode("/",$doj);
        $y1=explode("/",$now);

        $yy=$x[2];
        $mm=$x[0];
        $dd=$x[1];

        $yy1=$y1[2];
        $mm1=$y1[0];
        $dd1=$y1[1];
        $mn=0;
        $mn1=0;
        $ye=0;
        if($mm1>$mm)
        {
            $mn=$mm1-$mm;
            if($dd1<$dd)
            {
                $mn=$mn-1;
            }
            $ye=$yy1-$yy;
        }
        else if($mm1<$mm)
        {
            $mn=12-$mm;
            //$mn=$mn;

            if($mm!=1)
            {
                $mn1=$mm1-1;
            }

            $mn+=$mn1;
            if($dd1>$dd)
            {
                $mn+=1;
            }

            $yy=$yy+1;
            $ye=$yy1-$yy;
        }
        else
        {
            $ye=$yy1-$yy;
            $ye=$ye-1;

            $mn=12-1;

            if($dd1>$dd)
            {
                $ye+=1;
                $mn=0;
            }
        }

        $to=$ye." year and ".$mn." months";
        return $ye.".".$mn;

        /*return daysDiff($x[2],$x[0],$x[1]);
         $days=dateDiff("/",$now,$doj)/$year_diff;
        $days_exp=explode(".",$days);
        return $years_exp=$days; //number of years exp*/
    }
?>
0
user386431

Carbon pourrait également être un chemin à parcourir.

De leur site web:

Une simple extension PHP API pour DateTime. http://carbon.nesbot.com/

Exemple:

use Carbon\Carbon;

//...

$day1 = Carbon::createFromFormat('Y-m-d H:i:s', '2006-04-12 12:30:00');
$day2 = Carbon::createFromFormat('Y-m-d H:i:s', '2006-04-14 11:30:00');

echo $day1->diffInHours($day2); // 47

//...

Carbon étend la classe DateTime pour hériter des méthodes comprenant diff(). Il ajoute des sucres de Nice comme diffInHours, diffInMintutes, diffInSeconds etc.

0
joshuamabina

Pour passer un horodatage Unix, utilisez cette notation

$now        = time();
$now        = new DateTime("@$now");
0
Steve Whitby