Tính tổng số giây trong PHP DateInterval


99

Cách tốt nhất để tính tổng số giây giữa hai ngày là gì? Cho đến nay, tôi đã thử một cái gì đó dọc theo dòng:

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

Tuy nhiên, thuộc daystính của đối tượng DateInterval dường như bị hỏng trong bản dựng PHP5.3 hiện tại (ít nhất là trên Windows, nó luôn trả về cùng một 6015giá trị). Tôi cũng đã cố gắng làm điều đó theo cách không bảo toàn được số ngày trong mỗi tháng (làm tròn đến 30), năm nhuận, v.v.:

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

Nhưng tôi thực sự không hài lòng với việc sử dụng giải pháp nửa vời này.


Kết quả là $delta->format("%r%s")gì?
warrenm

1
@warrenm Vấn đề với formatlà khi nói số giây là 0 trong khi số phút là 1, $delta->format("%r%s")hóa ra là 0 :(
Vadim Samokhin

4
Tệ hơn nữa, nói như ai đó hiện đang sửa chữa một lỗi mắc phải trong quá trình đánh giá mã từ một lập trình viên đã dán mã EXACT của bạn ở trên - không phải tháng nào cũng có 30 ngày và không phải năm nào cũng có 365 ngày. :) [Chỉnh sửa: và người lập trình đó có thể là chính tôi!]
taiganaut

Câu trả lời:


205

Thay vào đó, bạn có thể không so sánh các tem thời gian được không?

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

11
Tôi đoán tôi đã không RTFM ... Đây là những gì tôi đang tìm kiếm; cảm ơn rất nhiều!
efritz

3
+1: đẹp và sạch sẽ! Lưu ý rằng getTimestamp()phương thức có sẵn trong PHP> = 5.3.0.
Sk8erPeter

6
Nếu bạn gặp khó khăn với PHP 5.2 trên hoster được chia sẻ tồi tệ của mình, hãy sử dụng format('U')thay thế getTimestamp().
chiborg

4
Giải pháp của bạn không tương thích w / năm 2038 lỗi
Jack M.

9
@JackM. Tốt để biết. Tôi hy vọng bất cứ thứ gì đang được xây dựng hiện nay sẽ không chạy nữa vào năm 2037. Vui lòng cung cấp giải pháp thay thế an toàn cho lỗi năm 2038.
Ben

34

Chức năng này cho phép bạn nhận tổng thời lượng tính bằng giây từ một đối tượng DateInterval

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

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

2
Cần lưu ý rằng DateTimeImmutable chỉ có sẵn từ PHP 5.5 trở lên.
hschmieder

Tôi nghĩ rằng bạn phải thay thế các biến trả về $endTime$referencevới nhau, vì điều này cho tôi kết quả trừ với giá trị ngày giờ trong khoảng thời gian trong tương lai.
AlexioVay

Tôi cũng không nghĩ Dấu thời gian tính bằng Giây. PHP DateTime = API kinh
dị

5

Bạn có thể làm như thế này:

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

$differenceInSeconds = $currentTime - $timeInPast;

time () trả về thời gian hiện tại tính bằng giây kể từ thời điểm kỷ nguyên (1970-01-01T00: 00: 00) và strtotime cũng làm tương tự, nhưng dựa trên ngày / giờ cụ thể mà bạn đưa ra.


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

Luôn luôn cảm thấy tuyệt vời khi những gì bạn cần đã có mặt trong lớp. Trong trường hợp của bạn, bạn cần tổng số giây. Tại sao không tạo ra một lớp học từ đó? Mã có thể trông như thế:

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

Bên cạnh tính trực quan, bạn cũng có thể hưởng lợi từ cơ sở tự động hoàn thành IDE của mình.

Để triển khai hữu ích hơn, bạn có thể xem thư viện này .


-8

Bạn có thể chỉ cần nhập các số cứng (thay vì 60 * 60 - đặt trong 3600) để không cần phải tính toán chúng mỗi lần.

Chỉnh sửa - sửa số dựa trên nhận xét của bạn.


Điều đó sẽ ổn thôi, và nó có thể chạy nhanh hơn một phần giây trong PHP, nhưng nó vẫn khiến tôi tính toán sai tương tự như ví dụ trên.
efritz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.