php 用PHP计算两个日期之间的小时数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3108591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 08:42:09  来源:igfitidea点击:

Calculate number of hours between 2 dates in PHP

phpdatetime

提问by Thinker

How do I calculate the difference between two dates in hours?

如何以小时为单位计算两个日期之间的差异?

For example:

例如:

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

In this case the result should be 47 hours.

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

回答by Fidi

The newer PHP-Versions provide some new classes called DateTime, DateInterval, DateTimeZoneand DatePeriod. The cool thing about this classes is, that it considers different timezones, leap years, leap seconds, summertime, etc. And on top of that it's very easy to use. Here's what you want with the help of this objects:

较新的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');

The DateInterval-object, which is returned also provides other methods than format. If you want the result in hours only, you could to something like this:

返回的 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;

And here are the links for documentation:

以下是文档链接:

All these classes also offer a procedural/functional way to operate with dates. Therefore take a look at the overview: http://php.net/manual/book.datetime.php

所有这些类还提供了一种程序/功能方式来操作日期。因此,看看概述:http: //php.net/manual/book.datetime.php

回答by Jan Han?i?

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

回答by fyrye

To provide another method for DatePeriodwhen using the UTCor GMTtimezone.

提供另一种DatePeriod使用UTCGMT时区的方法。

Count Hours https://3v4l.org/Mu3HD

数小时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)';

Result

结果

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


Count Hours with Daylight Savings https://3v4l.org/QBQUB

使用夏令时计算小时https://3v4l.org/QBQUB

Please be advised that DatePeriodexcludes an hour for DST but does not add another hour when DST ends. So its usage is subjective to your desired outcome and date range.

请注意,DatePeriodDST 不包括一小时,但不会在 DST 结束时再增加一小时。因此,它的使用取决于您想要的结果和日期范围。

See the current bug report

查看当前的错误报告

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

Result

结果

#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)

回答by Sergey Eremin

your answer is:

你的答案是:

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

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

回答by Walter Tross

The easiest way to get the correct number of hours between two dates (datetimes), even across daylight saving time changes, is to use the difference in Unix timestamps. Unix timestamps are seconds elapsed since 1970-01-01T00:00:00 UTC, ignoring leap seconds (this is OK because you probably don't need this precision, and because it's quite difficult to take leap seconds into account).

获得两个日期(日期时间)之间的正确小时数的最简单方法,即使在夏令时更改中也是如此,是使用 Unix 时间戳的差异。Unix 时间戳是自 1970-01-01T00:00:00 UTC 以来经过的秒数,忽略闰秒(这是可以的,因为您可能不需要这种精度,并且因为很难将闰秒考虑在内)。

The most flexible way to convert a datetime string with optional timezone information into a Unix timestamp is to construct a DateTimeobject (optionally with a DateTimeZoneas a second argument in the constructor), and then call its getTimestampmethod.

将带有可选时区信息的日期时间字符串转换为 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";

回答by Hoàng V? Tgtt

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

回答by Boris Delormas

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

I guess strtotime() function accept this date format.

我猜 strtotime() 函数接受这种日期格式。

回答by Night Walker

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

?>

回答by Arth

Unfortunately the solution provided by FaileN doesn't work as stated by Walter Tross.. days may not be 24 hours!

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

I like to use the PHP Objects where possible and for a bit more flexibility I have come up with the following function:

我喜欢在可能的情况下使用 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;
}

This like date_diff()creates a DateTimeInterval, but with the highest unit as hours rather than years.. it can be formatted as usual.

这就像date_diff()创建一个DateTimeInterval,但最高单位是小时而不是年..它可以像往常一样格式化。

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

N.B.I have used format('U')instead of getTimestamp()because of the comment in the manual. Also note that 64-bit is required for post-epoch and pre-negative-epoch dates!

NB我使用format('U')而不是getTimestamp()因为手册中的注释。另请注意,post-epoch 和 pre-negative-epoch 日期需要 64 位!

回答by Arth

This function helps you to calculate exact years and months between two given dates, $doj1and $doj. It returns example 4.3 means 4 years and 3 month.

此函数可帮助您计算两个给定日期$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("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*/
    }
?>