คำนวณวินาทีทั้งหมดใน PHP DateInterval


101

วิธีที่ดีที่สุดในการคำนวณจำนวนวินาทีทั้งหมดระหว่างวันที่สองวันคืออะไร? จนถึงตอนนี้ฉันได้ลองทำอะไรบางอย่างตาม:

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

อย่างไรก็ตามdaysคุณสมบัติของอ็อบเจ็กต์ DateInterval ดูเหมือนจะใช้งานไม่ได้ในบิลด์ PHP5.3 ปัจจุบัน (อย่างน้อยใน 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);

แต่ฉันไม่ค่อยพอใจกับการใช้วิธีแก้ปัญหาแบบ half-assed นี้


เป็นผลมาจาก$delta->format("%r%s")อะไร?
warrenm

1
@warrenm ปัญหาformatคือเมื่อบอกว่าจำนวนวินาทีเป็น 0 ในขณะที่จำนวนนาทีคือ 1 $delta->format("%r%s")กลายเป็น 0 :(
Vadim Samokhin

4
ที่แย่กว่านั้นคือตอนนี้มีบางคนกำลังแก้ไขข้อบกพร่องที่ติดอยู่ในการตรวจสอบโค้ดจากผู้เขียนโค้ดที่วางรหัสที่แน่นอนของคุณด้านบนไม่ใช่ทุก ๆ เดือนจะมี 30 วันและไม่ใช่ทุก ๆ ปีจะมี 365 วัน :) [แก้ไข: และผู้เข้ารหัสนั้นอาจเป็นตัวฉันเอง!]
taiganaut

คำตอบ:


216

คุณไม่สามารถเปรียบเทียบการประทับเวลาแทนได้หรือไม่?

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

12
ฉันเดาว่าฉันไม่ใช่ RTFM ... นี่คือสิ่งที่ฉันกำลังมองหา ขอบคุณมาก!
efritz

3
+1: สวยและสะอาด! โปรดทราบว่าgetTimestamp()เมธอดมีอยู่ใน PHP> = 5.3.0
Sk8erPeter

6
หากคุณติด PHP 5.2 ในโฮสต์ที่ใช้ร่วมกันเส็งเคร็งให้ใช้format('U')แทนgetTimestamp()ไฟล์.
chiborg

4
โซลูชันของคุณเข้ากันไม่ได้กับบั๊กปี 2038
Jack M.

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();
}

2
ควรสังเกตว่า DateTimeImmutable มีให้ใช้งานตั้งแต่ PHP 5.5 ขึ้นไปเท่านั้น
hschmieder

ฉันคิดว่าคุณต้องแทนที่ตัวแปรผลตอบแทน$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;
}

-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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.