计算PHP中两个date之间的小时数

我如何计算两个date之间的差异?

例如:

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

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

较新的PHP版本提供了一些称为DateTimeDateIntervalDateTimeZoneDatePeriod新类。 关于这个课程的很酷的事情是,它考虑不同的时区,闰年,闰秒,夏季等。最重要的是,这是非常容易使用。 这是你想要的这个对象的帮助:

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

这里是文档的链接:

  • DateTime的级
  • DateTimeZone级
  • DateInterval级
  • DatePeriod级

所有这些课程还提供程序/function方式来操作date。 因此,看看概述: http : //php.net/manual/book.datetime.php

 $t1 = StrToTime ( '2006-04-14 11:30:00' ); $t2 = StrToTime ( '2006-04-12 12:30:00' ); $diff = $t1 - $t2; $hours = $diff / ( 60 * 60 ); 

你的答案是:

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

在两个date(date时间)之间获得正确的小时数的最简单方法是使用Unix时间戳中的差异,即使在夏时制时间更改的情况下也是如此。 Unix时间戳是自1970-01-01T00:00:00 UTC以来经过的秒数,忽略了闰秒(这是可以的,因为你可能不需要这个精度,而且考虑到闰秒是相当困难的)。

将具有可选时区信息的date时间string转换为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"; 

DatePeriod提供另一种方法。

考虑到适用时区的夏令时,不需要在date之间的秒数或小时数上进行任何计算。

计算时间 (例如: 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'; 

结果

 47 hours 

用夏时制计算小时数 (例如: 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'; 

结果

 3623 hours 

同样的方法可以用来确定支付期限和检索date,而不是对它们进行计数。

支付期限 (例如: 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('Ym-d'), 'end' => $payPeriods[0]->format('Ym-d') ], 'previous' => [ 'start' => $payPeriods[2]->format('Ym-d'), 'end' => $payPeriods[1]->format('Ym-d') ] ]; var_dump($recent); 

结果

 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" } } 
 //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); 
 $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()函数接受这个date格式。

 <? $day1 = "2014-01-26 12:30:00"; $day1 = strtotime($day1); $day2 = "2014-01-26 11:30:00"; $day2 = strtotime($day2); $diffHours = round(($day2 - $day1) / 3600); echo $diffHours; ?> 

它适合我! 🙂

不幸的是,FaileN所提供的解决scheme并不像Walter Tross所说的那样工作..天可能不是24小时!

我喜欢在可能的情况下使用PHP对象,并提供更多的灵活性我已经提出了以下function:

 /** * @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()创build一个DateTimeInterval ,但最高单位小时而不是年数..它可以像往常一样格式化。

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

NB由于手册中的注释,我使用了format('U')而不是getTimestamp() 。 另外请注意,后期和前负面时代的date需要64位!

此function可帮助您计算两个给定date( $doj1$doj之间的确切年份和月份。 它返回示例4.3意味着4年3个月。

 <?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("Ymd 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*/ } ?> 

这是在我的项目中工作。 我想,这会对你有所帮助。

如果date在过去,那么反转将会是1。
如果date在将来,则反转将为0。

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

要传递一个unix时间戳,使用这个表示法

 $now = time(); $now = new DateTime("@$now");