计算PHP中2个日期之间的小时数

Thi*_*ker 98 php datetime

如何计算两个小时之间的差异小时数?

例如:

day1=2006-04-12 12:30:00
day2=2006-04-14 11:30:00
Run Code Online (Sandbox Code Playgroud)

在这种情况下,结果应该是47小时.

Ale*_*ich 188

较新的PHP版本提供了一些新类叫DateTime,DateInterval,DateTimeZoneDatePeriod.这个类很酷的事情是,它认为不同的时区,闰年,闰秒,夏季等,并上它很容易使用上面.在这些对象的帮助下,这就是你想要的:

// 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');
Run Code Online (Sandbox Code Playgroud)

返回的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;
Run Code Online (Sandbox Code Playgroud)

以下是文档链接:

所有这些类还提供了操作日期的程序/功能方法.因此,请查看概述:http://php.net/manual/book.datetime.php

  • 这个答案是对的.一天不总是24小时! (9认同)
  • 如果有人遇到了与我刚才所做的相同的问题,那里`$ diff-> d`等于0(因为我试图计算两个日期之间相隔2个月的小时数):运行`var_dump($ diff)`显示我另一个参数:`["days"] => int(61)`,所以我最终使用`$ hours = $ diff-> days*24;`,它接近1440小时的"平均值"给了2个30天的月份,所以看起来比0的结果要好得多.(猜猜我的PHP版本有点旧......) (3认同)
  • @Amal Murali,所以你决定将奖金奖励给这个答案,这是错误的?您是否尝试使用此答案计算在任何具有夏令时(夏令时)的时区中1月1日中午和6月1日中午之间的小时数?你会得到一个均匀的结果,而真正的结果是奇怪的. (3认同)
  • 我的意思是,在世界许多地方,每年有一个23小时工作日和一个25小时工作日. (2认同)

Jan*_*čič 69

$t1 = strtotime( '2006-04-14 11:30:00' );
$t2 = strtotime( '2006-04-12 12:30:00' );
$diff = $t1 - $t2;
$hours = $diff / ( 60 * 60 );
Run Code Online (Sandbox Code Playgroud)

  • 为什么不`$ diff/3600`? (4认同)
  • @AlexG这只是一种风格的东西.相同的输出,但程序员通常在时间上使用乘法 (3认同)

fyr*_*rye 20

提供另一种方法DatePeriod.

它考虑了适用时区的夏令时,无需对日期之间的秒数或小时数进行任何数学计算.

计数小时数 (例如:https://3v4l.org/Vom6N)

$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)';
Run Code Online (Sandbox Code Playgroud)

结果

47 hours (iterator_count)
47 hours (60 * 60)
47 hours (days * 24)
Run Code Online (Sandbox Code Playgroud)

用夏令时计算小时数 (例如:https://3v4l.org/eO9KE)

//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';
Run Code Online (Sandbox Code Playgroud)

结果

#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)
Run Code Online (Sandbox Code Playgroud)

相同的方法可用于确定支付期和检索日期而不是计算它们.

支付期限 (例如:https://3v4l.org/WQoh5)

$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)';
Run Code Online (Sandbox Code Playgroud)

结果

47 hours (iterator_count)
47 hours (60 * 60)
47 hours (days * 24)
Run Code Online (Sandbox Code Playgroud)


Ser*_*min 16

你的答案是:

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

  • 如果之间有2小时30分钟怎么办?你的答案将导致3个小时.我认为使用地板会更好,这样可以产生2个小时.真的取决于情况. (3认同)

Wal*_*oss 13

在两个日期(日期时间)之间获得正确小时数的最简单方法是使用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";
Run Code Online (Sandbox Code Playgroud)