PHP DateInterval'da toplam saniye hesaplayın


101

İki tarih arasındaki toplam saniye sayısını hesaplamanın en iyi yolu nedir? Şimdiye kadar, şu satırlarda bir şey denedim:

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

Ancak, daysDateInterval nesnesinin özelliği mevcut PHP5.3 yapısında bozuk görünüyor (en azından Windows'ta her zaman aynı 6015değeri döndürür ). Ayrıca bunu her aydaki gün sayısını (30'a yuvarlar), artık yılları vb. Koruyamayacak şekilde yapmaya çalıştım:

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

Ama bu yarım yamalak çözümü kullanmaktan gerçekten memnun değilim.


Sonucu ne olur $delta->format("%r%s")?
warrenm

1
@warrenm Sorun format, saniye sayısının 0 olduğunu ve dakika sayısının 0 olduğunu söylediğinizde $delta->format("%r%s")0 :(
Vadim Samokhin

4
Daha da kötüsü, yukarıdaki KESİN kodunuzu yapıştıran bir kodlayıcının kod incelemesinde yakalanan bir kusuru düzelten biri olarak konuşmak gerekirse - her ayın 30 günü ve her yılın 365 günü yoktur. :) [Düzenleme: ve bu kodlayıcı ben olabilirim!]
taiganaut

Yanıtlar:


212

Bunun yerine zaman damgalarını karşılaştıramaz mısın?

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

11
Sanırım RTFM yapmadım ... Aradığım buydu; çok teşekkürler!
efritz

3
+1: güzel ve temiz! getTimestamp()Yöntemin PHP> = 5.3.0'da mevcut olduğunu unutmayın .
Sk8erPeter

6
Eğer berbat paylaşılan barındırıcınızda PHP 5.2 ile sıkışıp kaldıysanız, format('U')yerine kullanın getTimestamp().
chiborg

4
Çözümünüz 2038 hatasıyla uyumlu değil
Jack M.

9
@JackM. Bunu bildiğim iyi oldu. Umarım şu anda inşa edilen şey 2037'de artık çalışmıyordur. 2038 yılı için hata korumalı alternatif bir çözüm sunmaktan çekinmeyin.
Ben

34

Bu işlev, bir DateInterval nesnesinden toplam süreyi saniye cinsinden almanızı sağlar

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

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

2
DateTimeImmutable'ın yalnızca PHP 5.5 veya daha yüksek sürümlerde mevcut olduğuna dikkat edilmelidir.
hschmieder

Geri dönüş değişkenlerini $endTimeve $referencebirbirinizle değiştirmeniz gerektiğini düşünüyorum , çünkü bu bana gelecekteki bir aralık tarih saat değeriyle eksi bir sonuç veriyor.
AlexioVay

Zaman Damgasının da Saniye cinsinden olduğunu sanmıyorum. PHP DateTime = Horrific API
Quadrivium

5

Bunu şu şekilde yapabilirsin:

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

$differenceInSeconds = $currentTime - $timeInPast;

time (), dönem zamanından (1970-01-01T00: 00: 00) bu yana geçerli saati saniye cinsinden döndürür ve strtotime da aynı şeyi yapar, ancak verdiğiniz belirli bir tarih / saate göre.


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

Zaman zaman güzel hissediyor Ne ihtiyacınız zaten sınıf olarak bulunur. Sizin durumunuzda, toplam saniye sayısına ihtiyacınız var. Neden bundan bir ders çıkarmıyorsun? Kod şöyle görünebilir:

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

Sezgisel olmanın yanı sıra, IDE'nizin otomatik tamamlama özelliğinden de yararlanabilirsiniz.

Daha kullanışlı uygulama için bu kitaplığa göz atabilirsiniz .


-8

Sabit sayıları (60 * 60 yerine - 3600 yerine) koyabilirsiniz, böylece her seferinde onları hesaplamasına gerek kalmaz.

Düzenle - yorumunuza göre sayı düzeltildi.


Bu iyi olurdu ve muhtemelen PHP'de saniyenin bir kısmını daha hızlı çalıştırırdı, ancak yine de yukarıdaki örnekte olduğu gibi aynı yanlış hesaplamayı bana bırakıyor.
efritz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.