Làm thế nào để tính toán sự khác biệt giữa hai ngày bằng PHP?


722

Tôi có hai ngày của mẫu:

Start Date: 2007-03-24 
End Date: 2009-06-26

Bây giờ tôi cần tìm sự khác biệt giữa hai cái này theo mẫu sau:

2 years, 3 months and 2 days

Làm thế nào tôi có thể làm điều này trong PHP?


1
2 năm 94 ngày. Tính toán các tháng, tính đến năm nhuận, sẽ có vấn đề. Làm thế nào chính xác điều này cần phải được?
dbasnett

Câu trả lời:


527

Sử dụng mã này cho mã kế thừa (PHP <5.3). Để biết giải pháp cập nhật, hãy xem câu trả lời của Jurka bên dưới

Bạn có thể sử dụng strtotime () để chuyển đổi hai ngày thành thời gian unix và sau đó tính số giây giữa chúng. Từ đó, việc tính toán các khoảng thời gian khác nhau khá dễ dàng.

$date1 = "2007-03-24";
$date2 = "2009-06-26";

$diff = abs(strtotime($date2) - strtotime($date1));

$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));

printf("%d years, %d months, %d days\n", $years, $months, $days);

Chỉnh sửa: Rõ ràng cách thức ưa thích để làm điều này giống như được mô tả bởi Jurka dưới đây. Mã của tôi thường chỉ được khuyến nghị nếu bạn không có PHP 5.3 trở lên.

Một số người trong các ý kiến ​​đã chỉ ra rằng mã ở trên chỉ là một xấp xỉ. Tôi vẫn tin rằng đối với hầu hết các mục đích đều ổn, vì việc sử dụng phạm vi nhiều hơn để mang lại cảm giác thời gian đã trôi qua hoặc vẫn còn hơn là để cung cấp độ chính xác - nếu bạn muốn làm điều đó, chỉ cần xuất ngày.

Mặc dù vậy, tôi đã quyết định giải quyết các khiếu nại. Nếu bạn thực sự cần một phạm vi chính xác nhưng chưa có quyền truy cập vào PHP 5.3, hãy sử dụng mã bên dưới (nó cũng hoạt động trong PHP 4). Đây là một cổng trực tiếp của mã mà PHP sử dụng nội bộ để tính toán phạm vi, ngoại trừ việc nó không mất thời gian tiết kiệm ánh sáng ban ngày. Điều đó có nghĩa là tối đa là một giờ, nhưng ngoại trừ điều đó là chính xác.

<?php

/**
 * Calculate differences between two dates with precise semantics. Based on PHPs DateTime::diff()
 * implementation by Derick Rethans. Ported to PHP by Emil H, 2011-05-02. No rights reserved.
 * 
 * See here for original code:
 * http://svn.php.net/viewvc/php/php-src/trunk/ext/date/lib/tm2unixtime.c?revision=302890&view=markup
 * http://svn.php.net/viewvc/php/php-src/trunk/ext/date/lib/interval.c?revision=298973&view=markup
 */

function _date_range_limit($start, $end, $adj, $a, $b, $result)
{
    if ($result[$a] < $start) {
        $result[$b] -= intval(($start - $result[$a] - 1) / $adj) + 1;
        $result[$a] += $adj * intval(($start - $result[$a] - 1) / $adj + 1);
    }

    if ($result[$a] >= $end) {
        $result[$b] += intval($result[$a] / $adj);
        $result[$a] -= $adj * intval($result[$a] / $adj);
    }

    return $result;
}

function _date_range_limit_days($base, $result)
{
    $days_in_month_leap = array(31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    $days_in_month = array(31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

    _date_range_limit(1, 13, 12, "m", "y", &$base);

    $year = $base["y"];
    $month = $base["m"];

    if (!$result["invert"]) {
        while ($result["d"] < 0) {
            $month--;
            if ($month < 1) {
                $month += 12;
                $year--;
            }

            $leapyear = $year % 400 == 0 || ($year % 100 != 0 && $year % 4 == 0);
            $days = $leapyear ? $days_in_month_leap[$month] : $days_in_month[$month];

            $result["d"] += $days;
            $result["m"]--;
        }
    } else {
        while ($result["d"] < 0) {
            $leapyear = $year % 400 == 0 || ($year % 100 != 0 && $year % 4 == 0);
            $days = $leapyear ? $days_in_month_leap[$month] : $days_in_month[$month];

            $result["d"] += $days;
            $result["m"]--;

            $month++;
            if ($month > 12) {
                $month -= 12;
                $year++;
            }
        }
    }

    return $result;
}

function _date_normalize($base, $result)
{
    $result = _date_range_limit(0, 60, 60, "s", "i", $result);
    $result = _date_range_limit(0, 60, 60, "i", "h", $result);
    $result = _date_range_limit(0, 24, 24, "h", "d", $result);
    $result = _date_range_limit(0, 12, 12, "m", "y", $result);

    $result = _date_range_limit_days(&$base, &$result);

    $result = _date_range_limit(0, 12, 12, "m", "y", $result);

    return $result;
}

/**
 * Accepts two unix timestamps.
 */
function _date_diff($one, $two)
{
    $invert = false;
    if ($one > $two) {
        list($one, $two) = array($two, $one);
        $invert = true;
    }

    $key = array("y", "m", "d", "h", "i", "s");
    $a = array_combine($key, array_map("intval", explode(" ", date("Y m d H i s", $one))));
    $b = array_combine($key, array_map("intval", explode(" ", date("Y m d H i s", $two))));

    $result = array();
    $result["y"] = $b["y"] - $a["y"];
    $result["m"] = $b["m"] - $a["m"];
    $result["d"] = $b["d"] - $a["d"];
    $result["h"] = $b["h"] - $a["h"];
    $result["i"] = $b["i"] - $a["i"];
    $result["s"] = $b["s"] - $a["s"];
    $result["invert"] = $invert ? 1 : 0;
    $result["days"] = intval(abs(($one - $two)/86400));

    if ($invert) {
        _date_normalize(&$a, &$result);
    } else {
        _date_normalize(&$b, &$result);
    }

    return $result;
}

$date = "1986-11-10 19:37:22";

print_r(_date_diff(strtotime($date), time()));
print_r(_date_diff(time(), strtotime($date)));

1
Nếu bạn đang sử dụng lớp DateTime, bạn có thể sử dụng định dạng $ date-> ('U') để lấy dấu thời gian unix.
Jon Cram

4
Điều đó không đúng nếu bạn phải đối phó với thời gian mùa hè / mùa đông. Trong trường hợp cụ thể này khi bạn điều chỉnh thời gian mùa hè / mùa đông, một ngày bằng 23 hoặc 25 giờ.
Arno

4
Vâng, lập luận tương tự có thể được đưa ra trong những năm nhuận. Nó cũng không tính đến điều đó. Tuy nhiên, tôi không tin rằng bạn thậm chí muốn tính đến điều đó vì chúng ta đang thảo luận về một phạm vi ở đây. Các ngữ nghĩa cho một phạm vi có phần khác nhau so với một ngày tuyệt đối.
Emil H

9
Chức năng này không chính xác. Nó tốt cho một xấp xỉ, nhưng không chính xác cho phạm vi chính xác. Đối với một người, nó giả định có 30 ngày trong một tháng, có nghĩa là nó sẽ có cùng một ngày khác nhau giữa ngày 1 tháng 2 và ngày 1 tháng 3 như ngày 1 tháng 7 đến ngày 1 tháng 8 (bất kể năm nhuận).
enobrev

1
Trong PHP, các biến tham chiếu nằm trong chữ ký hàm, không phải là cuộc gọi. Di chuyển tất cả của bạn &để chữ ký.
Paul Tarjan

909

Tôi đề nghị sử dụng các đối tượng DateTime và DateInterval.

$date1 = new DateTime("2007-03-24");
$date2 = new DateTime("2009-06-26");
$interval = $date1->diff($date2);
echo "difference " . $interval->y . " years, " . $interval->m." months, ".$interval->d." days "; 

// shows the total amount of days (not divided into years, months and days like above)
echo "difference " . $interval->days . " days ";

đọc thêm php DateTime :: hướng dẫn sử dụng khác

Từ hướng dẫn:

Kể từ PHP 5.2.2, các đối tượng DateTime có thể được so sánh bằng các toán tử so sánh.

$date1 = new DateTime("now");
$date2 = new DateTime("tomorrow");

var_dump($date1 == $date2); // bool(false)
var_dump($date1 < $date2);  // bool(true)
var_dump($date1 > $date2);  // bool(false)

14
+1 DateTime xử lý đúng năm nhuận và múi giờ và có một cuốn sách hay cho kệ: phparch.com/books/ mẹo
hakre

3
Có phương pháp nào cho tổng số giây giữa hai DateTimes không? (không thêm các thành phần, nghĩa là)
potatoe

1
@Panique $ distance-> ngày và $ distance-> d là các biện pháp khác nhau. nhận xét của bạn ở trên là đúng "hiển thị tổng số ngày (không được chia thành năm, tháng và ngày như trên)"
Jurka

1
@potatoe Có lẽ bạn muốn $date2->format('U') - $date1->format('U').
Paulo Freitas

3
lưu ý rằng có một lỗi trong đó DateInterval có thuộc tính ngày không chính xác ( luôn là 6015 ) trên Windows với một số phiên bản PHP: bug.php.net/orms.php?id=51184 (tham khảo các nhận xét ở đó để sửa / khắc phục)
Pim Schaaf

73

Khóa học hành động tốt nhất là sử dụng các đối tượng DateTime(và DateInterval) của PHP . Mỗi ngày được gói gọn trong một DateTimeđối tượng và sau đó có thể tạo ra sự khác biệt giữa hai ngày:

$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");

Đối DateTimetượng sẽ chấp nhận bất kỳ định dạng strtotime()nào. Nếu cần một định dạng ngày cụ thể hơn nữa, DateTime::createFromFormat()có thể được sử dụng để tạo DateTimeđối tượng.

Sau khi cả hai đối tượng được khởi tạo, bạn trừ đi một đối tượng khác DateTime::diff().

$difference = $first_date->diff($second_date);

$differencebây giờ giữ một DateIntervalđối tượng với thông tin khác biệt. Một var_dump()hình như thế này:

object(DateInterval)
  public 'y' => int 0
  public 'm' => int 0
  public 'd' => int 20
  public 'h' => int 6
  public 'i' => int 56
  public 's' => int 30
  public 'invert' => int 0
  public 'days' => int 20

Để định dạng DateIntervalđối tượng, chúng tôi sẽ cần kiểm tra từng giá trị và loại trừ nó nếu nó là 0:

/**
 * Format an interval to show all existing components.
 * If the interval doesn't have a time component (years, months, etc)
 * That component won't be displayed.
 *
 * @param DateInterval $interval The interval
 *
 * @return string Formatted interval string.
 */
function format_interval(DateInterval $interval) {
    $result = "";
    if ($interval->y) { $result .= $interval->format("%y years "); }
    if ($interval->m) { $result .= $interval->format("%m months "); }
    if ($interval->d) { $result .= $interval->format("%d days "); }
    if ($interval->h) { $result .= $interval->format("%h hours "); }
    if ($interval->i) { $result .= $interval->format("%i minutes "); }
    if ($interval->s) { $result .= $interval->format("%s seconds "); }

    return $result;
}

Tất cả những gì còn lại bây giờ là gọi hàm của chúng ta trên $difference DateIntervalđối tượng:

echo format_interval($difference);

Và chúng tôi nhận được kết quả chính xác:

20 ngày 6 giờ 56 phút 30 giây

Mã hoàn chỉnh được sử dụng để đạt được mục tiêu:

/**
 * Format an interval to show all existing components.
 * If the interval doesn't have a time component (years, months, etc)
 * That component won't be displayed.
 *
 * @param DateInterval $interval The interval
 *
 * @return string Formatted interval string.
 */
function format_interval(DateInterval $interval) {
    $result = "";
    if ($interval->y) { $result .= $interval->format("%y years "); }
    if ($interval->m) { $result .= $interval->format("%m months "); }
    if ($interval->d) { $result .= $interval->format("%d days "); }
    if ($interval->h) { $result .= $interval->format("%h hours "); }
    if ($interval->i) { $result .= $interval->format("%i minutes "); }
    if ($interval->s) { $result .= $interval->format("%s seconds "); }

    return $result;
}

$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");

$difference = $first_date->diff($second_date);

echo format_interval($difference);

DateTime()không phải là một hàm, nó là một đối tượng và nó ở đó kể từ PHP 5.2. Hãy chắc chắn rằng máy chủ của bạn hỗ trợ nó.
Madara's Ghost

2
@SecondRikudo DateTime :: Diff cần PHP 5.3.0
PhoneixS

Chúng tôi có một vấn đề, trao đổi First_date thành second_date và chúng tôi sẽ nhận được kết quả tương tự? Tại sao không nói 0 ngày 0 giờ 0 phút 0 giây hoặc chỉ 0. Ví dụ: 2012-11-30 17:03:30 - 2012-12-21 00:00:00 và 2012-12-21 00:00:00 - 2012-11-30 17:03:30 có kết quả tương tự.
Nhà phát triển Egoist

Bởi vì diff cho bạn sự khác biệt giữa hai lần. Sự khác biệt không phải là 0 bất kể ngày nào đến sau.
Madara's Ghost

1
Đây là một câu trả lời thực sự tốt vì nó cung cấp một chức năng rõ ràng có thể được gọi từ bất cứ đâu trong một cơ sở mã mà không cần nhiều thời gian. Các câu trả lời khác cho phép bạn thả calcs lặp lại khi đang giải quyết các triệu chứng thay vì giải quyết vấn đề ... Yếu tố duy nhất tôi đã thêm (và hầu hết các bài đăng khác không đề cập đến vấn đề này) là số nhiều của các yếu tố $ inter nếu nhiều hơn 1.
nickhar

33

Xem giờ và phút và giây ..

$date1 = "2008-11-01 22:45:00"; 

$date2 = "2009-12-04 13:44:01"; 

$diff = abs(strtotime($date2) - strtotime($date1)); 

$years   = floor($diff / (365*60*60*24)); 
$months  = floor(($diff - $years * 365*60*60*24) / (30*60*60*24)); 
$days    = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));

$hours   = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24)/ (60*60)); 

$minuts  = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24 - $hours*60*60)/ 60); 

$seconds = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24 - $hours*60*60 - $minuts*60)); 

printf("%d years, %d months, %d days, %d hours, %d minuts\n, %d seconds\n", $years, $months, $days, $hours, $minuts, $seconds); 

7
Có lẽ điều này sẽ không cho kết quả chính xác.
Cá heo

8
Và là một giải pháp khủng khiếp trừ khi bạn buộc phải sử dụng một phiên bản PHP lỗi thời khủng khiếp ...
ndlowrey

2
Không phải như vậy KHÔ . Chẳng hạn, 60 * 60 * 24 được lặp lại 15 lần. Tái sử dụng sao chép-dán sống lâu!
Peter Mortensen

Năm nhuận thì sao? Một năm không phải là trung bình 365 ngày.
Peter Mortensen

Mã này giả định một tháng là trung bình 30 ngày. Ngay cả khi giả sử 365 ngày trong một năm, một tháng trung bình là 365/12 = 30,42 ngày (xấp xỉ).
Peter Mortensen

18

Hãy xem liên kết sau đây. Đây là câu trả lời tốt nhất mà tôi đã tìm thấy cho đến nay .. :)

function dateDiff ($d1, $d2) {

    // Return the number of days between the two dates:    
    return round(abs(strtotime($d1) - strtotime($d2))/86400);

} // end function dateDiff

Không quan trọng ngày nào sớm hơn hay muộn hơn khi bạn chuyển các tham số ngày. Hàm sử dụng giá trị tuyệt đối của PHP ABS () để luôn trả về số thứ tự là số ngày giữa hai ngày.

Hãy nhớ rằng số ngày giữa hai ngày KHÔNG bao gồm cả hai ngày. Vì vậy, nếu bạn đang tìm kiếm số ngày được biểu thị bằng tất cả các ngày giữa và kể cả ngày đã nhập, bạn sẽ cần thêm một (1) vào kết quả của hàm này.

Ví dụ: sự khác biệt (như được trả về bởi chức năng trên) giữa 2013 / 02-09 và 2013/02/14 là 5. Nhưng số ngày hoặc ngày được biểu thị bằng phạm vi ngày 2013 / 02-09 - 2013 / 02- 14 là 6.

http://www.bizinfosys.com/php/date-difference.html


Câu hỏi yêu cầu sự khác biệt là số năm, tháng và ngày, không phải tổng số ngày.
Peter Mortensen

14

Tôi đã bình chọn cho câu trả lời của Jurkacâu hỏi yêu thích của tôi, nhưng tôi có phiên bản tiền php.5.3 ...

Tôi thấy mình đang giải quyết một vấn đề tương tự - đó là cách tôi có được câu hỏi này ngay từ đầu - nhưng chỉ cần một sự khác biệt về giờ. Nhưng chức năng của tôi cũng đã giải quyết vấn đề này khá tốt và tôi không có nơi nào trong thư viện của riêng mình để giữ nó ở nơi nó sẽ không bị mất và bị lãng quên, vì vậy ... hy vọng điều này hữu ích với ai đó.

/**
 *
 * @param DateTime $oDate1
 * @param DateTime $oDate2
 * @return array 
 */
function date_diff_array(DateTime $oDate1, DateTime $oDate2) {
    $aIntervals = array(
        'year'   => 0,
        'month'  => 0,
        'week'   => 0,
        'day'    => 0,
        'hour'   => 0,
        'minute' => 0,
        'second' => 0,
    );

    foreach($aIntervals as $sInterval => &$iInterval) {
        while($oDate1 <= $oDate2){ 
            $oDate1->modify('+1 ' . $sInterval);
            if ($oDate1 > $oDate2) {
                $oDate1->modify('-1 ' . $sInterval);
                break;
            } else {
                $iInterval++;
            }
        }
    }

    return $aIntervals;
}

Và bài kiểm tra:

$oDate = new DateTime();
$oDate->modify('+111402189 seconds');
var_dump($oDate);
var_dump(date_diff_array(new DateTime(), $oDate));

Và kết quả:

object(DateTime)[2]
  public 'date' => string '2014-04-29 18:52:51' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'America/New_York' (length=16)

array
  'year'   => int 3
  'month'  => int 6
  'week'   => int 1
  'day'    => int 4
  'hour'   => int 9
  'minute' => int 3
  'second' => int 8

Tôi đã có ý tưởng ban đầu từ đây , mà tôi đã sửa đổi cho mục đích sử dụng của mình (và tôi hy vọng sửa đổi của mình cũng sẽ hiển thị trên trang đó).

Bạn có thể dễ dàng loại bỏ các khoảng thời gian bạn không muốn (nói "tuần") bằng cách xóa chúng khỏi $aIntervalsmảng hoặc có thể thêm một $aExcludetham số hoặc chỉ lọc chúng khi bạn xuất chuỗi.


Thật không may, điều này không trả lại điều tương tự như DateInterval vì tràn năm / tháng.
Stephen Harris

2
@StephenHarris: Tôi chưa kiểm tra điều này, nhưng bằng cách đọc mã tôi khá tự tin, nó sẽ trả về kết quả tương tự - với điều kiện bạn xóa weekchỉ mục trong $aIntervals(vì DateDiffkhông bao giờ sử dụng điều đó).
Alix Axel

Đây là một giải pháp tuyệt vời để tìm ngày xảy ra mỗi khoảng thời gian giữa hai ngày.
giữa các

14
<?php
    $today = strtotime("2011-02-03 00:00:00");
    $myBirthDate = strtotime("1964-10-30 00:00:00");
    printf("Days since my birthday: ", ($today - $myBirthDate)/60/60/24);
?>

Câu hỏi yêu cầu sự khác biệt là số năm , thángngày . Điều này tạo ra sự khác biệt như tổng số ngày.
Peter Mortensen

11

Tôi không biết bạn có đang sử dụng khung PHP hay không, nhưng rất nhiều khung PHP có thư viện ngày / giờ và người trợ giúp để giúp bạn không phát minh lại bánh xe.

Ví dụ CodeIgniter có timespan()chức năng. Chỉ cần nhập hai dấu thời gian Unix và nó sẽ tự động tạo ra kết quả như thế này:

1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes

http://codeigniter.com/user_guide/helpers/date_helper.html


8

Sử dụng ví dụ:

echo time_diff_string('2013-05-01 00:22:35', 'now');
echo time_diff_string('2013-05-01 00:22:35', 'now', true);

Đầu ra:

4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago

Chức năng :

function time_diff_string($from, $to, $full = false) {
    $from = new DateTime($from);
    $to = new DateTime($to);
    $diff = $to->diff($from);

    $diff->w = floor($diff->d / 7);
    $diff->d -= $diff->w * 7;

    $string = array(
        'y' => 'year',
        'm' => 'month',
        'w' => 'week',
        'd' => 'day',
        'h' => 'hour',
        'i' => 'minute',
        's' => 'second',
    );
    foreach ($string as $k => &$v) {
        if ($diff->$k) {
            $v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
        } else {
            unset($string[$k]);
        }
    }

    if (!$full) $string = array_slice($string, 0, 1);
    return $string ? implode(', ', $string) . ' ago' : 'just now';
}

Nếu tôi muốn xác định xem chênh lệch có lớn hơn 30 phút không, tôi nên làm gì?
Ofir Attia

@OfirAttia: bạn có một loạt các câu hỏi như thế ở đây trên SO, chỉ cần sử dụng tìm kiếm. Bản demo đơn giản
Glavić

7

Tôi có một số logic đơn giản cho điều đó:

<?php
    per_days_diff('2011-12-12','2011-12-29')
    function per_days_diff($start_date, $end_date) {
        $per_days = 0;
        $noOfWeek = 0;
        $noOfWeekEnd = 0;
        $highSeason=array("7", "8");

        $current_date = strtotime($start_date);
        $current_date += (24 * 3600);
        $end_date = strtotime($end_date);

        $seassion = (in_array(date('m', $current_date), $highSeason))?"2":"1";

        $noOfdays = array('');

        while ($current_date <= $end_date) {
            if ($current_date <= $end_date) {
                $date = date('N', $current_date);
                array_push($noOfdays,$date);
                $current_date = strtotime('+1 day', $current_date);
            }
        }

        $finalDays = array_shift($noOfdays);
        //print_r($noOfdays);
        $weekFirst = array("week"=>array(),"weekEnd"=>array());
        for($i = 0; $i < count($noOfdays); $i++)
        {
            if ($noOfdays[$i] == 1)
            {
                //echo "This is week";
                //echo "<br/>";
                if($noOfdays[$i+6]==7)
                {
                    $noOfWeek++;
                    $i=$i+6;
                }
                else
                {
                    $per_days++;
                }
                //array_push($weekFirst["week"],$day);
            }
            else if($noOfdays[$i]==5)
            {
                //echo "This is weekend";
                //echo "<br/>";
                if($noOfdays[$i+2] ==7)
                {
                    $noOfWeekEnd++;
                    $i = $i+2;
                }
                else
                {
                    $per_days++;
                }
                //echo "After weekend value:- ".$i;
                //echo "<br/>";
            }
            else
            {
                $per_days++;
            }
        }

        /*echo $noOfWeek;
          echo "<br/>";
          echo $noOfWeekEnd;
          echo "<br/>";
          print_r($per_days);
          echo "<br/>";
          print_r($weekFirst);
        */

        $duration = array("weeks"=>$noOfWeek, "weekends"=>$noOfWeekEnd, "perDay"=>$per_days, "seassion"=>$seassion);
        return $duration;
      ?>

Dường như có một cái gì đó bị thiếu ở cuối mã mẫu (một dấu ngoặc kết thúc và " ?> "?).
Peter Mortensen

logic "đơn giản". Đây là ít nhất 40 dòng mã thuần.
Madjosz

6

Bạn có thể dùng

getdate()

Hàm trả về một mảng chứa tất cả các phần tử của ngày / thời gian được cung cấp:

$diff = abs($endDate - $startDate);
$my_t=getdate($diff);
print("$my_t[year] years, $my_t[month] months and $my_t[mday] days");

Nếu ngày bắt đầu và ngày kết thúc của bạn ở định dạng chuỗi thì hãy sử dụng

$startDate = strtotime($startDateStr);
$endDate = strtotime($endDateStr);

trước đoạn mã trên


dường như không hoạt động. Tôi có được một ngày vào đầu kỷ nguyên dấu thời gian.
Sirber

Điều quan trọng là phải hiểu rằng bạn cần phải làm một $my_t["year"] -= 1970để có được số năm chính xác. Bạn cũng cần phải trừ đi chênh lệch giờ của bạn từ GMT để có được số giờ đúng. Bạn cần phải trừ 1 từ tháng và ngày.
Salman A

6
// If you just want to see the year difference then use this function.
// Using the logic I've created you may also create month and day difference
// which I did not provide here so you may have the efforts to use your brain.
// :)
$date1='2009-01-01';
$date2='2010-01-01';
echo getYearDifference ($date1,$date2);
function getYearDifference($date1=strtotime($date1),$date2=strtotime($date2)){
    $year = 0;
    while($date2 > $date1 = strtotime('+1 year', $date1)){
        ++$year;
    }
    return $year;
}

Liệu "strtotime ('+ 1 năm', $ date1)" có tính đến năm nhuận không?
Peter Mortensen

6

Đây là chức năng của tôi. Yêu cầu PHP> = 5.3.4. Nó sử dụng lớp DateTime. Rất nhanh, nhanh và có thể tạo ra sự khác biệt giữa hai ngày hoặc thậm chí còn gọi là "thời gian kể từ khi".

if(function_exists('grk_Datetime_Since') === FALSE){
    function grk_Datetime_Since($From, $To='', $Prefix='', $Suffix=' ago', $Words=array()){
        #   Est-ce qu'on calcul jusqu'à un moment précis ? Probablement pas, on utilise maintenant
        if(empty($To) === TRUE){
            $To = time();
        }

        #   On va s'assurer que $From est numérique
        if(is_int($From) === FALSE){
            $From = strtotime($From);
        };

        #   On va s'assurer que $To est numérique
        if(is_int($To) === FALSE){
            $To = strtotime($To);
        }

        #   On a une erreur ?
        if($From === FALSE OR $From === -1 OR $To === FALSE OR $To === -1){
            return FALSE;
        }

        #   On va créer deux objets de date
        $From = new DateTime(@date('Y-m-d H:i:s', $From), new DateTimeZone('GMT'));
        $To   = new DateTime(@date('Y-m-d H:i:s', $To), new DateTimeZone('GMT'));

        #   On va calculer la différence entre $From et $To
        if(($Diff = $From->diff($To)) === FALSE){
            return FALSE;
        }

        #   On va merger le tableau des noms (par défaut, anglais)
        $Words = array_merge(array(
            'year'      => 'year',
            'years'     => 'years',
            'month'     => 'month',
            'months'    => 'months',
            'week'      => 'week',
            'weeks'     => 'weeks',
            'day'       => 'day',
            'days'      => 'days',
            'hour'      => 'hour',
            'hours'     => 'hours',
            'minute'    => 'minute',
            'minutes'   => 'minutes',
            'second'    => 'second',
            'seconds'   => 'seconds'
        ), $Words);

        #   On va créer la chaîne maintenant
        if($Diff->y > 1){
            $Text = $Diff->y.' '.$Words['years'];
        } elseif($Diff->y == 1){
            $Text = '1 '.$Words['year'];
        } elseif($Diff->m > 1){
            $Text = $Diff->m.' '.$Words['months'];
        } elseif($Diff->m == 1){
            $Text = '1 '.$Words['month'];
        } elseif($Diff->d > 7){
            $Text = ceil($Diff->d/7).' '.$Words['weeks'];
        } elseif($Diff->d == 7){
            $Text = '1 '.$Words['week'];
        } elseif($Diff->d > 1){
            $Text = $Diff->d.' '.$Words['days'];
        } elseif($Diff->d == 1){
            $Text = '1 '.$Words['day'];
        } elseif($Diff->h > 1){
            $Text = $Diff->h.' '.$Words['hours'];
        } elseif($Diff->h == 1){
            $Text = '1 '.$Words['hour'];
        } elseif($Diff->i > 1){
            $Text = $Diff->i.' '.$Words['minutes'];
        } elseif($Diff->i == 1){
            $Text = '1 '.$Words['minute'];
        } elseif($Diff->s > 1){
            $Text = $Diff->s.' '.$Words['seconds'];
        } else {
            $Text = '1 '.$Words['second'];
        }

        return $Prefix.$Text.$Suffix;
    }
}

6

Tôi muốn sử dụng date_createdate_diffcác đối tượng.

Mã số:

$date1 = date_create("2007-03-24");
$date2 = date_create("2009-06-26");

$dateDifference = date_diff($date1, $date2)->format('%y years, %m months and %d days');

echo $dateDifference;

Đầu ra:

2 years, 3 months and 2 days

Để biết thêm thông tin đọc hướng dẫn sử dụng PHPdate_diff

Theo hướng dẫn date_difflà một bí danh của DateTime :: diff ()


5

Điều này sẽ cố gắng phát hiện xem dấu thời gian có được đưa ra hay không và cũng sẽ trả về ngày / lần trong tương lai dưới dạng giá trị âm:

<?php

function time_diff($start, $end = NULL, $convert_to_timestamp = FALSE) {
  // If $convert_to_timestamp is not explicitly set to TRUE,
  // check to see if it was accidental:
  if ($convert_to_timestamp || !is_numeric($start)) {
    // If $convert_to_timestamp is TRUE, convert to timestamp:
    $timestamp_start = strtotime($start);
  }
  else {
    // Otherwise, leave it as a timestamp:
    $timestamp_start = $start;
  }
  // Same as above, but make sure $end has actually been overridden with a non-null,
  // non-empty, non-numeric value:
  if (!is_null($end) && (!empty($end) && !is_numeric($end))) {
    $timestamp_end = strtotime($end);
  }
  else {
    // If $end is NULL or empty and non-numeric value, assume the end time desired
    // is the current time (useful for age, etc):
    $timestamp_end = time();
  }
  // Regardless, set the start and end times to an integer:
  $start_time = (int) $timestamp_start;
  $end_time = (int) $timestamp_end;

  // Assign these values as the params for $then and $now:
  $start_time_var = 'start_time';
  $end_time_var = 'end_time';
  // Use this to determine if the output is positive (time passed) or negative (future):
  $pos_neg = 1;

  // If the end time is at a later time than the start time, do the opposite:
  if ($end_time <= $start_time) {
    $start_time_var = 'end_time';
    $end_time_var = 'start_time';
    $pos_neg = -1;
  }

  // Convert everything to the proper format, and do some math:
  $then = new DateTime(date('Y-m-d H:i:s', $$start_time_var));
  $now = new DateTime(date('Y-m-d H:i:s', $$end_time_var));

  $years_then = $then->format('Y');
  $years_now = $now->format('Y');
  $years = $years_now - $years_then;

  $months_then = $then->format('m');
  $months_now = $now->format('m');
  $months = $months_now - $months_then;

  $days_then = $then->format('d');
  $days_now = $now->format('d');
  $days = $days_now - $days_then;

  $hours_then = $then->format('H');
  $hours_now = $now->format('H');
  $hours = $hours_now - $hours_then;

  $minutes_then = $then->format('i');
  $minutes_now = $now->format('i');
  $minutes = $minutes_now - $minutes_then;

  $seconds_then = $then->format('s');
  $seconds_now = $now->format('s');
  $seconds = $seconds_now - $seconds_then;

  if ($seconds < 0) {
    $minutes -= 1;
    $seconds += 60;
  }
  if ($minutes < 0) {
    $hours -= 1;
    $minutes += 60;
  }
  if ($hours < 0) {
    $days -= 1;
    $hours += 24;
  }
  $months_last = $months_now - 1;
  if ($months_now == 1) {
    $years_now -= 1;
    $months_last = 12;
  }

  // "Thirty days hath September, April, June, and November" ;)
  if ($months_last == 9 || $months_last == 4 || $months_last == 6 || $months_last == 11) {
    $days_last_month = 30;
  }
  else if ($months_last == 2) {
    // Factor in leap years:
    if (($years_now % 4) == 0) {
      $days_last_month = 29;
    }
    else {
      $days_last_month = 28;
    }
  }
  else {
    $days_last_month = 31;
  }
  if ($days < 0) {
    $months -= 1;
    $days += $days_last_month;
  }
  if ($months < 0) {
    $years -= 1;
    $months += 12;
  }

  // Finally, multiply each value by either 1 (in which case it will stay the same),
  // or by -1 (in which case it will become negative, for future dates).
  // Note: 0 * 1 == 0 * -1 == 0
  $out = new stdClass;
  $out->years = (int) $years * $pos_neg;
  $out->months = (int) $months * $pos_neg;
  $out->days = (int) $days * $pos_neg;
  $out->hours = (int) $hours * $pos_neg;
  $out->minutes = (int) $minutes * $pos_neg;
  $out->seconds = (int) $seconds * $pos_neg;
  return $out;
}

Ví dụ sử dụng:

<?php
  $birthday = 'June 2, 1971';
  $check_age_for_this_date = 'June 3, 1999 8:53pm';
  $age = time_diff($birthday, $check_age_for_this_date)->years;
  print $age;// 28

Hoặc là:

<?php
  $christmas_2020 = 'December 25, 2020';
  $countdown = time_diff($christmas_2020);
  print_r($countdown);

5

"nếu" ngày được lưu trữ trong MySQL, tôi thấy việc tính toán chênh lệch ở cấp cơ sở dữ liệu dễ dàng hơn ... Sau đó, dựa trên kết quả Ngày, Giờ, Tối thiểu, Giây, phân tích và hiển thị kết quả phù hợp ...

mysql> select firstName, convert_tz(loginDate, '+00:00', '-04:00') as loginDate, TIMESTAMPDIFF(DAY, loginDate, now()) as 'Day', TIMESTAMPDIFF(HOUR, loginDate, now())+4 as 'Hour', TIMESTAMPDIFF(MINUTE, loginDate, now())+(60*4) as 'Min', TIMESTAMPDIFF(SECOND, loginDate, now())+(60*60*4) as 'Sec' from User_ where userId != '10158' AND userId != '10198' group by emailAddress order by loginDate desc;
 +-----------+---------------------+------+------+------+--------+
 | firstName | loginDate           | Day  | Hour | Min  | Sec    |
 +-----------+---------------------+------+------+------+--------+
 | Peter     | 2014-03-30 18:54:40 |    0 |    4 |  244 |  14644 |
 | Keith     | 2014-03-30 18:54:11 |    0 |    4 |  244 |  14673 |
 | Andres    | 2014-03-28 09:20:10 |    2 |   61 | 3698 | 221914 |
 | Nadeem    | 2014-03-26 09:33:43 |    4 |  109 | 6565 | 393901 |
 +-----------+---------------------+------+------+------+--------+
 4 rows in set (0.00 sec)

5

Tôi tìm thấy bài viết của bạn trên trang sau, trong đó có một số tài liệu tham khảo cho các tính toán thời gian ngày của PHP .

Tính toán sự khác biệt giữa hai Ngày (và thời gian) bằng PHP. Trang sau cung cấp một loạt các phương pháp khác nhau (tổng cộng 7) để thực hiện tính toán ngày / giờ bằng PHP, để xác định sự khác biệt về thời gian (giờ, munites), ngày, tháng hoặc năm giữa hai ngày.

Xem Thời gian ngày của PHP - 7 phương pháp để tính toán sự khác biệt giữa 2 ngày .


4

Bạn cũng có thể sử dụng mã sau để trả về ngày khác bằng cách phân số tròn lên $ date1 = $ duedate; // gán ngày đáo hạn echo $ date2 = date ("Ymd"); // ngày hiện tại $ ts1 = strtotime ($ date1); $ ts2 = strtotime ($ date2); $ giây_diff = $ ts1 - $ ts2; echo $ dateiff = ceil (($ giây_diff / 3600) / 24); // trở lại sau vài ngày

Nếu bạn sử dụng phương thức sàn của php thay vì trần, nó sẽ trả về cho bạn phần tròn. Vui lòng kiểm tra sự khác biệt ở đây, đôi khi nếu múi giờ của máy chủ dàn của bạn khác thì múi giờ của trang trực tiếp trong trường hợp đó bạn có thể nhận được kết quả khác nhau để thay đổi điều kiện cho phù hợp.


4
$date1 = date_create('2007-03-24');
$date2 = date_create('2009-06-26');
$interval = date_diff($date1, $date2);
echo "difference : " . $interval->y . " years, " . $interval->m." months, ".$interval->d." days ";

4

bạn luôn có thể sử dụng chức năng sau có thể trả về tuổi theo năm và tháng (tức là 1 năm 4 tháng)

function getAge($dob, $age_at_date)
{  
    $d1 = new DateTime($dob);
    $d2 = new DateTime($age_at_date);
    $age = $d2->diff($d1);
    $years = $age->y;
    $months = $age->m;

    return $years.'.'.months;
}

hoặc nếu bạn muốn tính tuổi ở ngày hiện tại, bạn có thể sử dụng

function getAge($dob)
{  
    $d1 = new DateTime($dob);
    $d2 = new DateTime(date());
    $age = $d2->diff($d1);
    $years = $age->y;
    $months = $age->m;

    return $years.'.'.months;
}

4

Đối với phiên bản php> = 5.3: Tạo hai đối tượng ngày và sau đó sử dụng date_diff()hàm. Nó sẽ trả về đối tượng php DateInterval . xem tài liệu

$date1=date_create("2007-03-24");
$date2=date_create("2009-06-26");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");

4

Đây là mã runnable

$date1 = date_create('2007-03-24');
$date2 = date_create('2009-06-26');
$diff1 = date_diff($date1,$date2);
$daysdiff = $diff1->format("%R%a");
$daysdiff = abs($daysdiff);

3

Tôi đã có cùng một vấn đề với PHP 5.2 và đã giải quyết nó với MySQL. Có thể không chính xác những gì bạn đang tìm kiếm, nhưng điều này sẽ thực hiện thủ thuật và trả về số ngày:

$datediff_q = $dbh->prepare("SELECT DATEDIFF(:date2, :date1)");
$datediff_q->bindValue(':date1', '2007-03-24', PDO::PARAM_STR);
$datediff_q->bindValue(':date2', '2009-06-26', PDO::PARAM_STR);
$datediff = ($datediff_q->execute()) ? $datediff_q->fetchColumn(0) : false;

Thêm thông tin tại đây http://dev.mysql.com/doc/refman/5.5/en/date-and-time-fifts.html#feft_datediff


3

Vì tất cả mọi người đang đăng mẫu mã, đây là một phiên bản khác.

Tôi muốn một chức năng để hiển thị sự khác biệt từ vài giây đến nhiều năm (chỉ một đơn vị). Trong khoảng thời gian hơn 1 ngày, tôi muốn nó quay vòng vào nửa đêm (10 giờ sáng thứ Hai được nhìn thấy từ 9 giờ sáng thứ Tư là 2 ngày trước, không phải 1). Và trong khoảng thời gian hơn một tháng, tôi muốn tái đầu tư vào cùng một ngày trong tháng (bao gồm 30,31 tháng ngày và năm nhuận).

Đây là những gì tôi nghĩ ra:

/**
 * Returns how long ago something happened in the past, showing it
 * as n seconds / minutes / hours / days / weeks / months / years ago.
 *
 * For periods over a day, it rolls over at midnight (so doesn't depend
 * on current time of day), and it correctly accounts for month-lengths
 * and leap-years (months and years rollover on current day of month).
 *
 * $param string $timestamp in DateTime format
 * $return string description of interval
 */
function ago($timestamp)
{
    $then = date_create($timestamp);

    // for anything over 1 day, make it rollover on midnight
    $today = date_create('tomorrow'); // ie end of today
    $diff = date_diff($then, $today);

    if ($diff->y > 0) return $diff->y.' year'.($diff->y>1?'s':'').' ago';
    if ($diff->m > 0) return $diff->m.' month'.($diff->m>1?'s':'').' ago';
    $diffW = floor($diff->d / 7);
    if ($diffW > 0) return $diffW.' week'.($diffW>1?'s':'').' ago';
    if ($diff->d > 1) return $diff->d.' day'.($diff->d>1?'s':'').' ago';

    // for anything less than 1 day, base it off 'now'
    $now = date_create();
    $diff = date_diff($then, $now);

    if ($diff->d > 0) return 'yesterday';
    if ($diff->h > 0) return $diff->h.' hour'.($diff->h>1?'s':'').' ago';
    if ($diff->i > 0) return $diff->i.' minute'.($diff->i>1?'s':'').' ago';
    return $diff->s.' second'.($diff->s==1?'':'s').' ago';
}

3

Cách đây một thời gian tôi đã viết một format_datechức năng vì điều này cung cấp nhiều tùy chọn về cách bạn muốn ngày của bạn :

function format_date($date, $type, $seperator="-")
{
    if($date)
    {
        $day = date("j", strtotime($date));
        $month = date("n", strtotime($date));
        $year = date("Y", strtotime($date));
        $hour = date("H", strtotime($date));
        $min = date("i", strtotime($date));
        $sec = date("s", strtotime($date));

        switch($type)
        {
            case 0:  $date = date("Y".$seperator."m".$seperator."d",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 1:  $date = date("D, F j, Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 2:  $date = date("d".$seperator."m".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 3:  $date = date("d".$seperator."M".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 4:  $date = date("d".$seperator."M".$seperator."Y h:i A",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 5:  $date = date("m".$seperator."d".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 6:  $date = date("M",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 7:  $date = date("Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 8:  $date = date("j",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 9:  $date = date("n",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 10: 
                     $diff = abs(strtotime($date) - strtotime(date("Y-m-d h:i:s"))); 
                     $years = floor($diff / (365*60*60*24));
                     $months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
                     $days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
                     $date = $years . " years, " . $months . " months, " . $days . "days";
        }
    }
    return($date);
}    

2
Câu trả lời này cũng sai như câu trả lời của khaldonno. Nó giả định (trường hợp 10) rằng một năm có 365 ngày (mỗi năm thứ tư có 365 ngày (ngoại trừ quy tắc 100 năm / 400 năm cho lịch Gregorian)) và một tháng có 30 ngày (khoảng 30,42 ngày trong những năm không nhảy vọt). Ngay cả với các hằng số tốt hơn, nó chỉ đúng trung bình, không nhất thiết phải đúng cho bất kỳ hai ngày cụ thể.
Peter Mortensen

3

Rất đơn giản:

    <?php
        $date1 = date_create("2007-03-24");
        echo "Start date: ".$date1->format("Y-m-d")."<br>";
        $date2 = date_create("2009-06-26");
        echo "End date: ".$date2->format("Y-m-d")."<br>";
        $diff = date_diff($date1,$date2);
        echo "Difference between start date and end date: ".$diff->format("%y years, %m months and %d days")."<br>";
    ?>

Vui lòng kiểm tra liên kết sau để biết chi tiết:

PHP: date_diff - Thủ công

Lưu ý rằng đó là phiên bản PHP 5.3.0 trở lên.


3

Một chức năng dễ dàng

function time_difference($time_1, $time_2, $limit = null)
{

    $val_1 = new DateTime($time_1);
    $val_2 = new DateTime($time_2);

    $interval = $val_1->diff($val_2);

    $output = array(
        "year" => $interval->y,
        "month" => $interval->m,
        "day" => $interval->d,
        "hour" => $interval->h,
        "minute" => $interval->i,
        "second" => $interval->s
    );

    $return = "";
    foreach ($output AS $key => $value) {

        if ($value == 1)
            $return .= $value . " " . $key . " ";
        elseif ($value >= 1)
            $return .= $value . " " . $key . "s ";

        if ($key == $limit)
            return trim($return);
    }
    return trim($return);
}

Sử dụng như

echo time_difference ($time_1, $time_2, "day");

Sẽ trở lại như thế nào 2 years 8 months 2 days


3

Hãy thử câu trả lời rất đơn giản này bằng date_diff () , điều này đã được kiểm tra.

$date1 = date_create("2017-11-27");
$date2 = date_create("2018-12-29");
$diff=date_diff($date1,$date2);
$months = $diff->format("%m months");
$years = $diff->format("%y years");
$days = $diff->format("%d days");

echo $years .' '.$months.' '.$days;

đầu ra là:

1 years 1 months 2 days

2

Tôi đang sử dụng hàm sau mà tôi đã viết, khi PHP 5.3 (tương ứng date_diff ()) không khả dụng:

        function dateDifference($startDate, $endDate)
        {
            $startDate = strtotime($startDate);
            $endDate = strtotime($endDate);
            if ($startDate === false || $startDate < 0 || $endDate === false || $endDate < 0 || $startDate > $endDate)
                return false;

            $years = date('Y', $endDate) - date('Y', $startDate);

            $endMonth = date('m', $endDate);
            $startMonth = date('m', $startDate);

            // Calculate months
            $months = $endMonth - $startMonth;
            if ($months <= 0)  {
                $months += 12;
                $years--;
            }
            if ($years < 0)
                return false;

            // Calculate the days
            $measure = ($months == 1) ? 'month' : 'months';
            $days = $endDate - strtotime('+' . $months . ' ' . $measure, $startDate);
            $days = date('z', $days);   

            return array($years, $months, $days);
        }

2

DateInterval là tuyệt vời nhưng nó có một vài cảnh báo:

  1. chỉ dành cho PHP 5.3+ ( nhưng đó thực sự không còn là lý do nữa )
  2. chỉ hỗ trợ năm, tháng, ngày, giờ, phút và giây (không có tuần)
  3. nó tính toán sự khác biệt với tất cả các ngày trên + (bạn không thể nhận được sự khác biệt chỉ trong vài tháng)

Để khắc phục điều đó, tôi đã mã hóa như sau (được cải thiện từ câu trả lời @enobrev ):

function date_dif($since, $until, $keys = 'year|month|week|day|hour|minute|second')
{
    $date = array_map('strtotime', array($since, $until));

    if ((count($date = array_filter($date, 'is_int')) == 2) && (sort($date) === true))
    {
        $result = array_fill_keys(explode('|', $keys), 0);

        foreach (preg_grep('~^(?:year|month)~i', $result) as $key => $value)
        {
            while ($date[1] >= strtotime(sprintf('+%u %s', $value + 1, $key), $date[0]))
            {
                ++$value;
            }

            $date[0] = strtotime(sprintf('+%u %s', $result[$key] = $value, $key), $date[0]);
        }

        foreach (preg_grep('~^(?:year|month)~i', $result, PREG_GREP_INVERT) as $key => $value)
        {
            if (($value = intval(abs($date[0] - $date[1]) / strtotime(sprintf('%u %s', 1, $key), 0))) > 0)
            {
                $date[0] = strtotime(sprintf('+%u %s', $result[$key] = $value, $key), $date[0]);
            }
        }

        return $result;
    }

    return false;
}

Nó chạy hai vòng; cái thứ nhất liên quan đến các khoảng tương đối (năm và tháng) thông qua cưỡng bức, và cái thứ hai tính các khoảng tuyệt đối bổ sung với số học đơn giản (vì vậy nhanh hơn):

echo humanize(date_dif('2007-03-24', '2009-07-31', 'second')); // 74300400 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'minute|second')); // 1238400 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'hour|minute|second')); // 20640 hours, 0 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|day')); // 2 years, 129 days
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week')); // 2 years, 18 weeks
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week|day')); // 2 years, 18 weeks, 3 days
echo humanize(date_dif('2007-03-24', '2009-07-31')); // 2 years, 4 months, 1 week, 0 days, 0 hours, 0 minutes, 0 seconds

function humanize($array)
{
    $result = array();

    foreach ($array as $key => $value)
    {
        $result[$key] = $value . ' ' . $key;

        if ($value != 1)
        {
            $result[$key] .= 's';
        }
    }

    return implode(', ', $result);
}

@PeterMortensen: Nó sẽ hoạt động, nhưng tôi không đảm bảo. Đặt múi giờ của bạn và cho nó đi.
Alix Axel
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.