在PHP中获取两个日期时间之间的间隔秒?

在PHP中获取两个日期时间之间的间隔秒?,php,datetime,Php,Datetime,2009-10-05 18:11:08 2009-10-05 18:07:13 这将生成235,如何执行此操作?您可以使用: $diff = strtotime('2009-10-05 18:11:08') - strtotime('2009-10-05 18:07:13') DateTime对象也可以采用类似的方法,例如 $date = new DateTime( '2009-10-05 18:07:13' ); $date2 = new DateTime( '2009-10-05 18:1

2009-10-05 18:11:08

2009-10-05 18:07:13

这将生成235,如何执行此操作?

您可以使用:

$diff = strtotime('2009-10-05 18:11:08') - strtotime('2009-10-05 18:07:13')
DateTime对象也可以采用类似的方法,例如

$date = new DateTime( '2009-10-05 18:07:13' );
$date2 = new DateTime( '2009-10-05 18:11:08' );

$diff = $date2->getTimestamp() - $date->getTimestamp();

PHP日期时间参考对以下内容很有帮助:

这可能是最好的办法

$seconds = strtotime('2009-10-05 18:11:08') - strtotime('2009-10-05 18:07:13')

对于DateTime对象,您可以这样做:

$date = new DateTime( '2009-10-05 18:07:13' );
$date2 = new DateTime( '2009-10-05 18:11:08' );

$diffInSeconds = $date2->getTimestamp() - $date->getTimestamp();

由于unix时代的限制,在比较1970年之前和2038年之后的日期时可能会遇到问题。我选择降低精度(=不看一秒钟),但避免通过unix历元转换(getTimestamp)。这取决于你要做什么

在我的例子中,使用365代替(12*30)和“30”作为平均月长,减少了可用输出中的错误

function DateIntervalToSec($start,$end){ // as datetime object returns difference in seconds
    $diff = $end->diff($start);
    $diff_sec = $diff->format('%r').( // prepend the sign - if negative, change it to R if you want the +, too
                ($diff->s)+ // seconds (no errors)
                (60*($diff->i))+ // minutes (no errors)
                (60*60*($diff->h))+ // hours (no errors)
                (24*60*60*($diff->d))+ // days (no errors)
                (30*24*60*60*($diff->m))+ // months (???)
                (365*24*60*60*($diff->y)) // years (???)
                );
    return $diff_sec;
}
请注意,如果“平均”数量用于差异,则错误可能为0。PHP文档没有提到这一点。。。 在坏情况下,错误可能是:

  • 如果对小于1个月的时间间隔应用差异,则为0秒
  • 如果将差异应用于大于1个月的时间间隔,则为0到3天
  • 如果将差异应用于大于1年的时间间隔,则为0至14天
我宁愿假设有人决定把“M”当作“30天”,而“Y”是365,当“差异”在不到30天的时间内走时……
如果有人知道更多关于这一点,并可以提供官方文件,欢迎

一个简单而精确的解决方案(以Nilz11的评论为例):


如果需要实时本地时间差,并且希望使用
getTimestamp
,则必须考虑计算期间的DST开关。因此,方程式中必须包括UTC的本地偏移量

以以下日期为例:

$tz = new \DateTimeZone("Europe/Berlin");
$start = new \DateTime("2018-02-01 12:00:00", $tz);
$end = new \DateTime("2018-04-01 12:00:00", $tz);
$start
在UTC中是“2018-02-01 11:00:00”,而
$end
在UTC中是“2018-04-01 10:00:00”。请注意,虽然柏林时区中的时间相同,但UTC中的时间不同。UTC偏移量在
$start
中为1小时,在
$end
中为2小时

请记住,
getTimestamp
始终返回UTC!因此,在查找实际的局部差异时,必须从时间戳中减去偏移量

// WRONG! returns 5094000, one hour too much due to DST in the local TZ
echo $end->getTimestamp() - $start->getTimestamp();

// CORRECT: returns 5090400
echo ($end->getTimestamp() - $end->getOffset()) - ($start->getTimestamp() - $start->getOffset());

对于那些担心使用时间戳的局限性(即使用1970年之前和2038年之后的日期)的人,您可以简单地以秒为单位计算差异,如下所示:

$start = new DateTime('2009-10-05 18:11:08');
$end = new DateTime('2009-10-05 18:07:13');
$diff = $end->diff($start);

$daysInSecs = $diff->format('%r%a') * 24 * 60 * 60;
$hoursInSecs = $diff->h * 60 * 60;
$minsInSecs = $diff->i * 60;

$seconds = $daysInSecs + $hoursInSecs + $minsInSecs + $diff->s;

echo $seconds; // output: 235

为那些有兴趣阅读更多内容的人写了一篇文章。

注意:当“较低”的时间是“现在”时,请确保使用大写字母“H”表示数小时(24小时模式),并使用
date()
获取现在的日期时间(
date(“Y-m-d H:i:s”)
)“``通过查看各个组件之间的分隔符,可以消除m/d/y或d-m-y格式中的日期歧义:如果分隔符是斜杠(/),则假定为美制m/d/y;而如果分隔符是破折号(-)或点(.),则假定为欧洲d-m-y格式。但是,如果年份以两位数格式给出,且分隔符为破折号(-),则日期字符串将解析为y-m-d。为避免潜在的歧义,最好使用ISO 8601(YYYY-MM-DD)日期或DateTime::createFromFormat()如果可能的话,``检查JCM答案并选择您的案例可能重复的使用days属性而不是d属性来获得两天之间的确切天数。因此没有不准确的结果。这也考虑了夏令时!这是这个问题最优雅的解决方案。这应该是公认的答案。注意t、 为了正确考虑夏令时,您需要提供正确的DateTimeZone。如果您的系统设置正确,那么php可能已经从系统默认值中知道了您的时区。如果有疑问,请手动实例化一个,如下所示:$tz=new DateTimeZone('Europe/Berlin'));并将其作为第二个参数传递给DateTime构造函数。这是一个很好的解决方案,但在较长的时间内(例如1小时),我会收到负值(溢出?),知道如何解决这个问题吗?这个答案是可怕的错误信息。我只是写了自己的测试用例来检查这个问题,我很高兴它完全错了。5094000%86400=82800。这是一整天的秒减去3600的“失踪小时”当时钟在DST边界提前一小时时。更简单的测试用例:“2019-03-31 01:59:59”和“2019-03-31 03:00:01”之间的时间戳差为2秒,这是正确的量。“2019-10-27 01:59:59”和“2019-10-27 02:00:01”之间的时间戳差是3602秒,这是正确的数量。有关此内容的详细信息:getTimestamp和setTimestamp指的是unix时间戳,它始终没有时区。您正在将无时区格式与时区偏移量混合。在“处理unix时间戳”中例如,您正在寻找3600+1=3720秒,因为时钟拨回一小时,而不是两小时。
// WRONG! returns 5094000, one hour too much due to DST in the local TZ
echo $end->getTimestamp() - $start->getTimestamp();

// CORRECT: returns 5090400
echo ($end->getTimestamp() - $end->getOffset()) - ($start->getTimestamp() - $start->getOffset());
$start = new DateTime('2009-10-05 18:11:08');
$end = new DateTime('2009-10-05 18:07:13');
$diff = $end->diff($start);

$daysInSecs = $diff->format('%r%a') * 24 * 60 * 60;
$hoursInSecs = $diff->h * 60 * 60;
$minsInSecs = $diff->i * 60;

$seconds = $daysInSecs + $hoursInSecs + $minsInSecs + $diff->s;

echo $seconds; // output: 235