Рассчитать количество часов между двумя датами в PHP - PullRequest
93 голосов
/ 24 июня 2010

Как рассчитать разницу между двумя датами в часах?

Например:

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

В этом случае результат должен составлять 47 часов.

Ответы [ 13 ]

178 голосов
/ 24 июня 2010

Более новые версии PHP предоставляют некоторые новые классы, называемые DateTime, DateInterval, DateTimeZone и DatePeriod.Крутая вещь в этом классе заключается в том, что он учитывает разные часовые пояса, високосные годы, високосные секунды, летнее время и т. Д. Кроме того, он очень прост в использовании.Вот что вы хотите с помощью этих объектов:

// 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');

Объект DateInterval, который возвращается, также предоставляет другие методы, отличные от format.Если вы хотите получить результат только в часах, вы можете сделать что-то вроде этого:

$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;

А вот ссылки на документацию:

Все эти классы также предлагают процедурный / функциональный способ работы с датами.Поэтому взгляните на обзор: http://php.net/manual/book.datetime.php

65 голосов
/ 24 июня 2010
$t1 = strtotime( '2006-04-14 11:30:00' );
$t2 = strtotime( '2006-04-12 12:30:00' );
$diff = $t1 - $t2;
$hours = $diff / ( 60 * 60 );
20 голосов
/ 04 марта 2016

Чтобы предоставить другой метод для DatePeriod при использовании UTC или GMT часовой пояс.

Количество часов https://3v4l.org/Mu3HD

$start = new \DateTime('2006-04-12T12:30:00');
$end = 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($start, $interval, $end);

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

//difference between Unix Epoch
$diff = $end->getTimestamp() - $start->getTimestamp();
$hours = $diff / ( 60 * 60 );
echo $hours . ' hours (60 * 60)';

//difference between days
$diff = $end->diff($start);
$hours = $diff->h + ($diff->days * 24);
echo $hours . ' hours (days * 24)';

Результат

47 hours (iterator_count)
47 hours (60 * 60)
47 hours (days * 24)

Подсчет часов с переходом на летнее время https://3v4l.org/QBQUB

Обратите внимание, что DatePeriod исключает один час для перехода на летнее время, но не добавляет еще один час, когда заканчивается летнее время. Поэтому его использование зависит от желаемого результата и диапазона дат.

См. Текущий отчет об ошибке

//set timezone to UTC to disregard daylight savings
date_default_timezone_set('America/New_York');

$interval = new \DateInterval('PT1H');

//DST starts Apr. 2nd 02:00 and moves to 03:00
$start = new \DateTime('2006-04-01T12:00:00');  
$end = new \DateTime('2006-04-02T12:00:00');

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

//DST ends Oct. 29th 02:00 and moves to 01:00
$start = new \DateTime('2006-10-28T12:00:00');
$end = new \DateTime('2006-10-29T12:00:00'); 

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

Результат

#2006-04-01 12:00 EST to 2006-04-02 12:00 EDT
23 hours (iterator_count)
//23 hours (60 * 60)
//24 hours (days * 24)

#2006-10-28 12:00 EDT to 2006-10-29 12:00 EST
24 hours (iterator_count)
//25 hours (60 * 60)
//24 hours (days * 24)

#2006-01-01 12:00 EST to 2007-01-01 12:00 EST
8759 hours (iterator_count)
//8760 hours (60 * 60)
//8760 hours (days * 24)

//------

#2006-04-01 12:00 UTC to 2006-04-02 12:00 UTC
24 hours (iterator_count)
//24 hours (60 * 60)
//24 hours (days * 24)

#2006-10-28 12:00 UTC to 2006-10-29 12:00 UTC
24 hours (iterator_count)
//24 hours (60 * 60)
//24 hours (days * 24)

#2006-01-01 12:00 UTC to 2007-01-01 12:00 UTC
8760 hours (iterator_count)
//8760 hours (60 * 60)
//8760 hours (days * 24)
16 голосов
/ 24 июня 2010

Ваш ответ:

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

12 голосов
/ 30 января 2014

Самый простой способ получить правильное количество часов между двумя датами (дата-время), даже при изменении летнего времени, - это использовать разницу в метках времени Unix.Временные метки Unix - это секунды, прошедшие с 1970-01-01T00: 00: 00 UTC, игнорируя високосные секунды (это нормально, потому что вам, вероятно, не нужна такая точность, и потому что довольно трудно учитывать високосные секунды).

Самый гибкий способ преобразования строки даты и времени с необязательной информацией о часовом поясе в метку времени Unix - это создание объекта DateTime (необязательно с DateTimeZone в качестве второго аргумента в конструкторе), а затем вызовите его метод getTimestamp .

$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";
4 голосов
/ 11 апреля 2014
//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);
3 голосов
/ 26 января 2014
<?
     $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 голосов
/ 24 июня 2010
$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);

Я полагаю, функция strtotime () принимает этот формат даты.

2 голосов
/ 06 мая 2015

К сожалению, решение, предоставленное FaileN, не работает, как заявлено Уолтером Троссом ... дни не могут быть 24 часа!

Мне нравится использовать объекты PHP, где это возможно, и для большей гибкостиПридумайте следующую функцию:

/**
 * @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;
}

Это подобно date_diff() создает DateTimeInterval, но с наивысшей единицей измерения в виде часов, а не лет ... ее можно отформатировать как обычно.1009 *

NB Я использовал format('U') вместо getTimestamp() из-за комментария в руководстве .Также обратите внимание, что 64-битный код требуется для дат после и до негативной эпохи!

0 голосов
/ 19 апреля 2018

Углерод это также может быть путь.

С их сайта:

Простое расширение PHP API для DateTime. http://carbon.nesbot.com/

Пример:

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 расширяет класс DateTime для наследования методов, включая diff(). Он добавляет хорошие сахара, такие как diffInHours, diffInMintutes, diffInSeconds e.t.c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...