Вычислить общее количество секунд в PHP DateInterval

101

Как лучше всего рассчитать общее количество секунд между двумя датами? До сих пор я пробовал что-то вроде:

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

Однако daysв текущей сборке PHP5.3 свойство объекта DateInterval кажется нарушенным (по крайней мере, в Windows оно всегда возвращает одно и то же 6015значение). Я также попытался сделать это таким образом, чтобы не сохранять количество дней в каждом месяце (округление до 30), високосные годы и т. Д .:

$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 05
1
@warrenm Проблема в formatтом, что когда говорят, что количество секунд равно 0, а количество минут равно 1, $delta->format("%r%s")оказывается 0 :(
Вадим Самохин
4
Что еще хуже, если говорить, что кто-то сейчас исправляет дефект, обнаруженный при проверке кода кодировщиком, который вставил ваш ТОЧНЫЙ код выше - не в каждом месяце 30 дней, и не в каждом году 365 дней. :) [Edit: а этим кодером мог быть я!]
тайганавт 02

Ответы:

213

Не могли бы вы вместо этого сравнить отметки времени ?

$now = new DateTime('now');
$diff = $date->getTimestamp() - $now->getTimestamp()
Бен
источник
11
Думаю, я не RTFM ... Это то, что я искал; большое спасибо!
efritz 05
3
+1: красиво и чисто! Обратите внимание, что getTimestamp()метод доступен в PHP> = 5.3.0.
Sk8erPeter
6
Если вы застряли с PHP 5.2 на своем дерьмовом хостере с общим доступом, используйте format('U')вместо getTimestamp().
chiborg
4
Ваше решение несовместимо с ошибкой 2038 года
Джек М.
9
@JackM. Хорошо знать. Я очень надеюсь, что все, что создается сейчас, больше не будет работать в 2037 году. Не стесняйтесь предоставить альтернативное решение, безопасное для ошибок 2038 года.
Бен
34

Эта функция позволяет получить общую продолжительность в секундах из объекта DateInterval.

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

    return $endTime->getTimestamp() - $reference->getTimestamp();
}
dave1010
источник
2
Следует отметить, что DateTimeImmutable доступен только в PHP 5.5 или выше.
hschmieder
Я думаю, вам нужно заменить возвращаемые переменные $endTimeи $referenceдруг на друга, поскольку это дает мне отрицательный результат с будущим значением интервала datetime.
AlexioVay 01
Я тоже не думаю, что метка времени в секундах. PHP DateTime = Horrific API
Quadrivium
5

Сделать это можно так:

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

$differenceInSeconds = $currentTime - $timeInPast;

time () возвращает текущее время в секундах с момента времени эпохи (1970-01-01T00: 00: 00), а strtotime делает то же самое, но в зависимости от указанной вами даты / времени.

xil3
источник
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;
}
хуфуз
источник
-1

Всегда приятно, когда то, что тебе нужно, уже присутствует в виде класса. В вашем случае вам нужно общее количество секунд. Почему бы не сделать из этого класс? Код мог выглядеть так:

(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 05