Hitung total detik dalam PHP DateInterval

99

Apa cara terbaik untuk menghitung jumlah total detik antara dua tanggal? Sejauh ini, saya telah mencoba sesuatu di sepanjang baris:

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

Namun, daysproperti objek DateInterval tampaknya rusak dalam build PHP5.3 saat ini (setidaknya di Windows, ia selalu mengembalikan nilai yang sama 6015). Saya juga mencoba melakukannya dengan cara yang tidak dapat mempertahankan jumlah hari dalam setiap bulan (putaran menjadi 30), tahun kabisat, dll:

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

Tapi saya benar-benar tidak senang menggunakan solusi setengah-setengah ini.

efritz
sumber
Apa hasil dari $delta->format("%r%s")?
warrenm
1
@warrenm Masalahnya formatadalah ketika mengatakan jumlah detik adalah 0 sedangkan jumlah menit adalah 1, $delta->format("%r%s")ternyata 0 :(
Vadim Samokhin
4
Lebih buruk lagi, berbicara sebagai seseorang yang sekarang memperbaiki cacat yang tertangkap dalam tinjauan kode dari pembuat kode yang menempelkan kode EXACT Anda di atas - tidak setiap bulan memiliki 30 hari, dan tidak setiap tahun memiliki 365 hari. :) [Sunting: dan pembuat kode itu mungkin saya sendiri!]
taiganaut

Jawaban:

205

Bisakah Anda tidak membandingkan cap waktu ?

$now = new DateTime('now');
$diff = $date->getTimestamp() - $now->getTimestamp()
Ben
sumber
11
Saya kira saya tidak melakukan RTFM ... Ini yang saya cari; Terima kasih banyak!
efritz
3
+1: bagus dan bersih! Perhatikan bahwa getTimestamp()metode ini tersedia dalam PHP> = 5.3.0.
Sk8erPeter
6
Jika Anda terjebak dengan PHP 5.2 di hoster bersama jelek Anda, gunakan format('U')saja getTimestamp().
chiborg
4
Solusi Anda tidak kompatibel dengan bug tahun 2038
Jack M.
9
@Tokopedia Senang mendengarnya. Saya berharap apa pun yang sedang dibangun sekarang tidak berjalan lagi di tahun 2037. Jangan ragu untuk memberikan solusi alternatif aman bug tahun 2038.
Ben
34

Fungsi ini memungkinkan Anda untuk mendapatkan total durasi dalam hitungan detik dari objek DateInterval

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

    return $endTime->getTimestamp() - $reference->getTimestamp();
}
dave1010
sumber
2
Perlu dicatat bahwa DateTimeImmutable hanya tersedia dari PHP 5.5 atau lebih tinggi.
hschmieder
Saya pikir Anda harus mengganti variabel kembali $endTimedan $referencesatu sama lain, karena ini memberi saya hasil minus dengan nilai datetime interval masa depan.
AlexioVay
Saya rasa Stempel Waktu juga tidak dalam Detik. PHP DateTime = API Mengerikan
Quadrivium
5

Anda bisa melakukannya seperti ini:

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

$differenceInSeconds = $currentTime - $timeInPast;

time () mengembalikan waktu saat ini dalam detik sejak waktu epoch (1970-01-01T00: 00: 00), dan strtotime melakukan hal yang sama, tetapi berdasarkan tanggal / waktu tertentu yang Anda berikan.

xil3
sumber
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;
}
hoofuz
sumber
0

Selalu terasa menyenangkan ketika yang Anda butuhkan sudah ada di kelas. Dalam kasus Anda, Anda membutuhkan total jumlah detik. Mengapa tidak membuat kelas dari itu? Kode tersebut akan terlihat seperti ini:

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

Selain intuitif, Anda juga bisa memanfaatkan fasilitas pelengkapan otomatis IDE Anda.

Untuk implementasi yang lebih berguna, Anda dapat melihat pustaka ini .

Vadim Samokhin
sumber
-8

Anda bisa memasukkan angka pasti (bukan 60 * 60 - masukkan 3600) sehingga tidak perlu menghitungnya setiap saat.

Edit - perbaiki nomor berdasarkan komentar Anda.

Duniyadnd
sumber
Itu akan baik-baik saja, dan mungkin akan berjalan sepersekian detik lebih cepat di PHP, tetapi masih menyisakan kesalahan perhitungan yang sama seperti contoh di atas.
efritz