计算PHP DateInterval中的总秒数


99

计算两个日期之间总秒数的最佳方法是什么?到目前为止,我已经尝试了以下方法:

$delta   = $date->diff(new DateTime('now'));
$seconds = $delta->days * 60 * 60 * 24;

但是,days在当前的PHP5.3版本中,DateInterval对象的属性似乎已损坏(至少在Windows上,它总是返回相同的6015值)。我还尝试过这样做,无法保留每个月的天数(四舍五入到30),leap年等:

$seconds = ($delta->s)
         + ($delta->i * 60)
         + ($delta->h * 60 * 60)
         + ($delta->d * 60 * 60 * 24)
         + ($delta->m * 60 * 60 * 24 * 30)
         + ($delta->y * 60 * 60 * 24 * 365);

但是我真的不满意使用这种半成品解决方案。


是什么结果$delta->format("%r%s")
warrenm

1
@warrenm的问题format是,说秒数为0而分钟数为1时,$delta->format("%r%s")结果为0 :(
Vadim Samokhin

4
更糟糕的是,就像现在有人要修复从粘贴了您的EXACT代码的编码器中发现的代码审查中的缺陷一样,不是每个月都有30天,也不是每年有365天。:) [编辑:那位编码员可能是我自己!]
taiganaut

Answers:


205

您可以不比较时间戳吗?

$now = new DateTime('now');
$diff = $date->getTimestamp() - $now->getTimestamp()

11
我想我不是RTFM ...这就是我想要的;非常感谢!
efritz

3
+1:干净整洁!请注意,该getTimestamp()方法在PHP> = 5.3.0中可用。
Sk8erPeter

6
如果您在糟糕的共享主机上坚持使用PHP 5.2,请使用format('U')代替getTimestamp()
chiborg 2012年

4
您的解决方案是不是瓦特/ 2038年的bug兼容
杰克M.

9
@杰克 很高兴知道。我确实希望现在正在建造的任何东西都不会在2037年运行。请随时提供2038年的bug安全替代解决方案。
2014年

34

此函数使您可以从DateInterval对象获取以秒为单位的总持续时间

/**
 * @param DateInterval $dateInterval
 * @return int seconds
 */
function dateIntervalToSeconds($dateInterval)
{
    $reference = new DateTimeImmutable;
    $endTime = $reference->add($dateInterval);

    return $endTime->getTimestamp() - $reference->getTimestamp();
}

2
应该注意的是,DateTimeImmutable仅可用于PHP 5.5或更高版本。
hschmieder,2015年

我认为你必须更换回变量$endTime$reference相互的,因为这给了我一个有前途的间隔时间值负的结果。
AlexioVay

我也不认为时间戳记秒。PHP DateTime =可怕的API
Quadrivium

5

您可以这样做:

$currentTime = time();
$timeInPast = strtotime("2009-01-01 00:00:00");

$differenceInSeconds = $currentTime - $timeInPast;

time()返回自纪元时间(1970-01-01T00:00:00)开始的当前时间(以秒为单位),strtotime也会执行相同的操作,但基于您指定的特定日期/时间。


4
static function getIntervalUnits($interval, $unit)
{
    // Day
    $total = $interval->format('%a');
    if ($unit == TimeZoneCalc::Days)
        return $total;
    //hour
    $total = ($total * 24) + ($interval->h );
    if ($unit == TimeZoneCalc::Hours)
        return $total;
    //min
    $total = ($total * 60) + ($interval->i );
    if ($unit == TimeZoneCalc::Minutes)
        return $total;  
    //sec
    $total = ($total * 60) + ($interval->s );
    if ($unit == TimeZoneCalc::Seconds)
        return $total;  

    return false;
}

0

它总是感觉很好的时候是什么,你需要的是已经存在的类。就您而言,您总共需要几秒钟。为什么不做一个这样的课程呢?代码看起来像这样:

(new TotalFullSeconds(
    new IntervalFromRange(
        new DateTimeFromISO8601String('2017-07-03T14:27:39+00:00'),
        new DateTimeFromISO8601String('2017-07-05T14:27:39+00:00')
    )
))
    ->value()

除了直观,您还可以受益于IDE的自动完成功能。

要实现更有用的实现,您可以签出这个库


-8

您可以只输入硬数字(而不是60 * 60-放入3600),这样就不必每次都计算它们。

编辑-根据您的评论修正数字。


很好,在PHP中运行速度可能会加快一秒钟,但是仍然给我带来了与上面的示例相同的错误计算。
efritz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.