Bagaimana cara menghitung perbedaan antara dua tanggal menggunakan PHP?

722

Saya memiliki dua tanggal formulir:

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

Sekarang saya perlu menemukan perbedaan antara keduanya dalam bentuk berikut:

2 years, 3 months and 2 days

Bagaimana saya bisa melakukan ini di PHP?

Taryn
sumber
1
2 tahun 94 hari. Menghitung bulan, dengan memperhitungkan tahun kabisat, akan bermasalah. Seberapa akurat hal ini diperlukan?
dbasnett
kemungkinan duplikat dari Bagaimana cara menghitung waktu relatif?
Cole Johnson

Jawaban:

527

Gunakan ini untuk kode lawas (PHP <5.3). Untuk solusi terkini lihat jawaban jurka di bawah ini

Anda dapat menggunakan strtotime () untuk mengonversi dua tanggal menjadi waktu unix dan kemudian menghitung jumlah detik di antaranya. Dari sini agak mudah untuk menghitung periode waktu yang berbeda.

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

Sunting: Jelas cara yang disukai untuk melakukan ini seperti dijelaskan oleh jurka di bawah ini. Kode saya umumnya hanya disarankan jika Anda tidak memiliki PHP 5.3 atau lebih baik.

Beberapa orang di komentar telah menunjukkan bahwa kode di atas hanyalah perkiraan. Saya masih percaya bahwa untuk sebagian besar tujuan itu baik-baik saja, karena penggunaan rentang lebih untuk memberikan rasa berapa banyak waktu telah berlalu atau tetap daripada memberikan presisi - jika Anda ingin melakukan itu, cukup tampilkan tanggal.

Terlepas dari semua itu, saya telah memutuskan untuk menangani keluhan. Jika Anda benar-benar membutuhkan kisaran yang tepat tetapi belum mendapatkan akses ke PHP 5.3, gunakan kode di bawah ini (ini juga bisa digunakan di PHP 4). Ini adalah port langsung dari kode yang digunakan PHP secara internal untuk menghitung rentang, dengan pengecualian bahwa itu tidak memperhitungkan waktu musim panas. Itu berarti paling tidak satu jam, tapi kecuali itu harus benar.

<?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)));
Emil H
sumber
1
Jika Anda menggunakan kelas DateTime, Anda bisa menggunakan format $ date-> ('U') untuk mendapatkan cap waktu unix.
Jon Cram
4
Itu tidak benar jika Anda harus berurusan dengan musim panas / musim dingin. Dalam kasus khusus ini ketika Anda menyesuaikan waktu musim panas / musim dingin, satu hari sama dengan 23 atau 25 jam.
Arno
4
Nah, argumen yang sama bisa dibuat untuk tahun kabisat. Itu tidak memperhitungkannya juga. Tetap saja, saya tidak yakin bahwa Anda bahkan ingin memperhitungkannya karena kami sedang mendiskusikan kisaran di sini. Semantik untuk rentang agak berbeda dari untuk tanggal absolut.
Emil H
9
Fungsi ini salah. Ini bagus untuk perkiraan, tetapi tidak tepat untuk rentang yang tepat. Untuk satu, ia mengasumsikan ada 30 hari dalam sebulan, yang artinya akan memiliki perbedaan hari yang sama antara 1 Februari dan 1 Maret seperti pada 1 Juli hingga 1 Agustus (terlepas dari tahun kabisat).
enobrev
1
Di PHP, variabel referensi ada di tanda tangan fungsi, bukan panggilan. Pindahkan semua milik Anda &ke tanda tangan.
Paul Tarjan
909

Saya menyarankan untuk menggunakan objek DateTime dan 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 ";

baca selengkapnya php DateTime :: diff manual

Dari manual:

Pada PHP 5.2.2, objek DateTime dapat dibandingkan dengan menggunakan operator perbandingan.

$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)
jurka
sumber
14
+1 DateTime menangani tahun kabisat dan zona waktu dengan benar dan ada buku bagus untuk rak: phparch.com/books/…
hakre
3
Apakah ada metode yang memberikan jumlah total detik antara kedua DateTimes? (tanpa menambahkan komponen, yaitu)
potatoe
1
@Panique $ interval-> hari dan $ interval-> d adalah ukuran yang berbeda. komentar Anda di atas benar "menunjukkan jumlah total hari (tidak dibagi menjadi tahun, bulan, dan hari-hari seperti di atas)"
jurka
1
@ potatoe Anda mungkin ingin $date2->format('U') - $date1->format('U').
Paulo Freitas
3
perhatikan bahwa ada bug di mana DateInterval memiliki properti hari salah ( selalu 6015 ) di Windows dengan beberapa versi PHP: bugs.php.net/bug.php?id=51184 (lihat komentar di sana untuk diperbaiki / diperbaiki)
Pim Schaaf
73

Tindakan terbaik adalah menggunakan objek PHP DateTime(dan DateInterval). Setiap tanggal dienkapsulasi dalam suatu DateTimeobjek, dan kemudian perbedaan antara keduanya dapat dibuat:

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

The DateTimeobjek akan menerima format apapun strtotime()akan. Jika diperlukan format tanggal yang lebih spesifik, DateTime::createFromFormat()dapat digunakan untuk membuat DateTimeobjek.

Setelah kedua objek dipakai, Anda mengurangi satu dari yang lain dengan DateTime::diff().

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

$differencesekarang memegang DateIntervalobjek dengan informasi perbedaan. A var_dump()terlihat seperti ini:

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

Untuk memformat DateIntervalobjek, kita perlu memeriksa setiap nilai dan mengecualikannya jika 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;
}

Yang tersisa sekarang adalah memanggil fungsi kita pada $difference DateIntervalobjek:

echo format_interval($difference);

Dan kami mendapatkan hasil yang benar:

20 hari 6 jam 56 menit 30 detik

Kode lengkap yang digunakan untuk mencapai tujuan:

/**
 * 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);
Hantu Madara
sumber
DateTime()bukan fungsi, itu objek, dan sudah ada sejak PHP 5.2. Pastikan server Anda mendukungnya.
Hantu Madara
2
@SecondRikudo DateTime :: Diff perlu PHP 5.3.0
PhoneixS
Kami memiliki masalah, bertukar first_date ke second_date dan kami mendapatkan hasil yang sama? Mengapa tidak mengatakan 0 hari 0 jam 0 menit 0 detik atau hanya 0. Contoh: 2012-11-30 17:03:30 - 2012-12-21 00:00:00 dan 2012-12-21 00:00:00 - 2012-11-30 17:03:30 mendapatkan hasil yang sama.
EgoistDeveloper
Karena diff memberi Anda perbedaan antara dua kali. Perbedaannya bukan 0 terlepas dari tanggal yang datang kemudian.
Hantu Madara
1
Ini adalah jawaban yang sangat bagus karena menyediakan fungsi yang jelas yang dapat dipanggil dari mana saja dalam basis kode tanpa banyak waktu. Jawaban yang lain memungkinkan Anda untuk melepaskan calcs yang di echo dengan cepat yang mengatasi gejala alih-alih menyelesaikan masalah ... Satu-satunya elemen yang saya tambahkan (dan hampir semua posting lainnya tidak membahas hal ini) adalah pluralisasi $ elemen interval jika lebih dari 1.
nickhar
33

Lihat Jam dan Minuts dan Detik ..

$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); 
khaldonno
sumber
7
Mungkin ini tidak akan memberikan hasil yang akurat.
Dolphin
8
Dan merupakan solusi yang mengerikan kecuali Anda dipaksa untuk menggunakan versi PHP yang sangat ketinggalan jaman ...
rdlowrey
2
Tidak terlalu KERING . Misalnya, 60 * 60 * 24 diulang 15 kali. Salin-tempel ulang pakai lama!
Peter Mortensen
Bagaimana dengan tahun kabisat? Satu tahun bukan rata-rata 365 hari.
Peter Mortensen
Kode ini mengasumsikan sebulan rata-rata 30 hari. Bahkan dengan asumsi 365 hari selama setahun, bulan rata-rata adalah 365/12 = 30,42 hari (rata-rata).
Peter Mortensen
18

Lihatlah tautan berikut. Ini jawaban terbaik yang saya temukan sejauh ini .. :)

function dateDiff ($d1, $d2) {

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

} // end function dateDiff

Tidak masalah tanggal mana yang lebih awal atau lebih lambat ketika Anda memasukkan parameter tanggal. Fungsi ini menggunakan nilai absolut PHP ABS () untuk selalu mengembalikan nomor postive sebagai jumlah hari antara kedua tanggal.

Perlu diingat bahwa jumlah hari antara kedua tanggal tersebut TIDAK termasuk kedua tanggal. Jadi jika Anda mencari jumlah hari yang diwakili oleh semua tanggal antara dan termasuk tanggal yang dimasukkan, Anda perlu menambahkan satu (1) ke hasil fungsi ini.

Misalnya, perbedaan (seperti yang dikembalikan oleh fungsi di atas) antara 2013-02-09 dan 2013-02-14 adalah 5. Tetapi jumlah hari atau tanggal yang diwakili oleh rentang tanggal 2013-02-09 - 2013-02- 14 adalah 6.

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

casper123
sumber
Pertanyaannya menanyakan perbedaannya seperti jumlah tahun, bulan dan hari, bukan jumlah hari.
Peter Mortensen
14

Saya memilih jurka 's jawaban seperti itulah favorit saya, tapi saya memiliki versi pre-php.5.3 ...

Saya menemukan diri saya mengerjakan masalah yang sama - yaitu bagaimana saya sampai pada pertanyaan ini - tetapi hanya perlu perbedaan dalam jam. Tapi fungsi saya menyelesaikan yang satu ini dengan cukup baik dan saya tidak punya tempat di perpustakaan saya sendiri untuk menyimpannya di tempat yang tidak akan hilang dan dilupakan, jadi ... semoga ini berguna bagi seseorang.

/**
 *
 * @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;
}

Dan tesnya:

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

Dan hasilnya:

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

Saya mendapatkan ide asli dari sini , yang saya modifikasi untuk penggunaan saya (dan saya harap modifikasi saya akan ditampilkan di halaman itu juga).

Anda dapat dengan mudah menghapus interval yang tidak Anda inginkan (katakan "minggu") dengan menghapusnya dari $aIntervalsarray, atau mungkin menambahkan $aExcludeparameter, atau cukup filter keluar ketika Anda menghasilkan string.

enobrev
sumber
Sayangnya ini tidak mengembalikan hal yang sama dengan DateInterval karena tahun / bulan meluap.
Stephen Harris
2
@StephenHarris: Saya belum menguji ini, tetapi dengan membaca kode saya cukup yakin itu akan mengembalikan hasil yang sama - asalkan Anda menghapus weekindeks $aIntervals(karena DateDifftidak pernah menggunakan itu).
Alix Axel
Ini adalah solusi yang bagus untuk menemukan tanggal yang terjadi setiap interval antara dua tanggal.
otak
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);
?>
vengat
sumber
Pertanyaannya menanyakan perbedaannya seperti jumlah tahun , bulan , dan hari . Ini menghasilkan perbedaan sebagai jumlah total hari.
Peter Mortensen
11

Saya tidak tahu apakah Anda menggunakan kerangka kerja PHP atau tidak, tetapi banyak kerangka kerja PHP memiliki pustaka / penolong tanggal / waktu untuk membantu menjaga Anda dari menciptakan kembali roda.

Misalnya CodeIgniter memiliki timespan()fungsi. Cukup masukkan dua cap waktu Unix dan secara otomatis akan menghasilkan hasil seperti ini:

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

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

Jake Wilson
sumber
8

Gunakan contoh:

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

Keluaran:

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

Fungsi:

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';
}
Glavić
sumber
jika saya ingin menentukan apakah perbedaannya lebih besar dari 30 menit, apa yang harus saya lakukan?
Ofir Attia
@OfirAttia: Anda memiliki banyak pertanyaan seperti itu di SO, cukup gunakan pencarian. Demo sederhana
Glavić
7

Saya punya beberapa logika sederhana untuk itu:

<?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;
      ?>
Hardik Raval
sumber
Tampaknya ada sesuatu yang hilang di akhir kode sampel (tanda kurung akhir dan " ?> "?).
Peter Mortensen
logika "sederhana". Ini adalah setidaknya 40 baris kode murni.
Madjosz
6

Anda dapat menggunakan

getdate()

fungsi yang mengembalikan array yang mengandung semua elemen dari tanggal / waktu yang disediakan:

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

Jika tanggal mulai dan berakhir Anda dalam format string maka gunakan

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

sebelum kode di atas

Mark Pim
sumber
sepertinya tidak berfungsi. Saya mendapatkan kencan di awal era timestamp.
Sirber
Penting untuk dipahami bahwa Anda perlu melakukan $my_t["year"] -= 1970untuk mendapatkan jumlah tahun yang benar. Anda juga perlu mengurangi perbedaan jam Anda dari GMT untuk mendapatkan jam yang tepat. Anda perlu mengurangi 1 dari bulan dan tanggal juga.
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;
}
ESC
sumber
Apakah "strtotime ('+ 1 tahun', $ date1)" memperhitungkan tahun kabisat?
Peter Mortensen
6

Ini adalah fungsi saya. Diperlukan PHP> = 5.3.4. Ini menggunakan kelas DateTime. Sangat cepat, cepat dan dapat melakukan perbedaan antara dua tanggal atau bahkan yang disebut "waktu sejak".

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;
    }
}
David Bélanger
sumber
6

Saya lebih suka menggunakan date_createdan date_diffobjek.

Kode:

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

Keluaran:

2 years, 3 months and 2 days

Untuk info lebih lanjut baca manual PHPdate_diff

Menurut manual date_diffadalah alias DateTime :: diff ()

Adeel
sumber
5

Ini akan mencoba mendeteksi apakah cap waktu diberikan atau tidak, dan juga akan mengembalikan tanggal / waktu mendatang sebagai nilai negatif:

<?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;
}

Contoh penggunaan:

<?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

Atau:

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

"jika" tanggal disimpan dalam MySQL, saya merasa lebih mudah untuk melakukan perhitungan perbedaan pada tingkat basis data ... Kemudian berdasarkan Hari, Jam, Min, Keluaran detik, hasil parsing dan tampilan yang sesuai ...

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)
Pemikiran elastis
sumber
5

Saya menemukan artikel Anda di halaman berikut, yang berisi sejumlah referensi untuk perhitungan waktu tanggal PHP .

Hitung perbedaan antara dua Tanggal (dan waktu) menggunakan PHP. Halaman berikut menyediakan berbagai metode yang berbeda (total 7) untuk melakukan perhitungan tanggal / waktu menggunakan PHP, untuk menentukan perbedaan waktu (jam, jam), hari, bulan atau tahun antara dua tanggal.

Lihat Waktu Tanggal PHP - 7 Metode untuk Menghitung Perbedaan antara 2 tanggal .

James - Pengembangan Php
sumber
4

Anda juga dapat menggunakan kode berikut untuk mengembalikan perbedaan tanggal dengan pecahan bulat hingga $ date1 = $ duedate; // berikan tanggal jatuh tempo echo $ date2 = date ("Ymd"); // tanggal saat ini $ ts1 = strtotime ($ date1); $ ts2 = strtotime ($ date2); $ seconds_diff = $ ts1 - $ ts2; echo $ datediff = ceil (($ seconds_diff / 3600) / 24); // kembali dalam beberapa hari

Jika Anda menggunakan metode lantai bukan php ceil itu akan mengembalikan Anda fraksi bulat turun. Silakan periksa perbedaannya di sini, beberapa kali jika zona waktu server pementasan Anda berbeda maka zona waktu situs langsung dalam hal ini Anda mungkin mendapatkan hasil yang berbeda sehingga ubah kondisinya.

Rikin Adhyapak
sumber
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 ";
liza
sumber
4

Anda selalu dapat menggunakan fungsi berikut yang dapat mengembalikan usia dalam tahun dan bulan (mis. 1 Tahun 4 Bulan)

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

atau jika Anda ingin usia dihitung pada tanggal saat ini, Anda dapat menggunakan

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

    return $years.'.'.months;
}
Rickus Harmse
sumber
4

Untuk versi php> = 5.3: Buat dua objek tanggal dan kemudian gunakan date_diff()fungsi. Ini akan mengembalikan objek DateInterval php . lihat dokumentasi

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

Ini adalah kode yang bisa dijalankan

$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);
Mosin
sumber
3

Saya memiliki masalah yang sama dengan PHP 5.2 dan menyelesaikannya dengan MySQL. Mungkin tidak persis seperti yang Anda cari, tetapi ini akan melakukan trik dan mengembalikan jumlah hari:

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

Info lebih lanjut di sini http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_datediff

Klemen Tušar
sumber
3

Karena semua orang memposting sampel kode, ini adalah versi lain.

Saya ingin fungsi untuk menampilkan perbedaan dari detik ke tahun (hanya satu unit). Untuk periode lebih dari 1 hari, saya ingin rollover pada tengah malam (jam 10 pagi hari Senin mulai jam 9 pagi hari Rabu adalah 2 hari yang lalu, bukan 1). Dan untuk periode lebih dari sebulan, saya ingin rollover berada pada hari yang sama dalam sebulan (termasuk untuk 30/31 hari bulan & tahun kabisat).

Inilah yang saya pikirkan:

/**
 * 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';
}
ChrisV
sumber
3

Beberapa waktu yang lalu saya menulis sebuah format_datefungsi karena ini memberikan banyak pilihan tentang bagaimana Anda menginginkan kencan Anda :

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);
}    
Juara
sumber
2
Jawaban ini sama salahnya dengan jawaban khaldonno. Diasumsikan (kasus 10) bahwa satu tahun memiliki 365 hari (setiap tahun keempat memiliki 366 hari (kecuali untuk aturan 100 tahun / 400 tahun untuk kalender Gregorian)), dan satu bulan memiliki 30 hari (sekitar 30,42 hari) dalam tahun-tahun non-kabisat). Bahkan dengan konstanta yang lebih baik, itu hanya benar secara rata-rata, belum tentu benar untuk dua tanggal tertentu.
Peter Mortensen
3

Sangat sederhana:

    <?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>";
    ?>

Silakan cek tautan berikut untuk detail:

PHP: date_diff - Manual

Perhatikan bahwa ini untuk PHP 5.3.0 atau lebih tinggi.

Choudhury Saadmaan Mahmid
sumber
3

Fungsi yang mudah

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

Gunakan seperti

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

Akan kembali seperti 2 years 8 months 2 days

Anuj
sumber
3

Coba jawaban yang sangat sederhana ini menggunakan date_diff () , ini diuji.

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

outputnya adalah:

1 years 1 months 2 days
larp
sumber
2

Saya menggunakan fungsi berikut yang saya tulis, ketika PHP 5.3 (masing-masing date_diff ()) tidak tersedia:

        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);
        }
Konstantin Shegunov
sumber
2

DateInterval hebat tetapi memiliki beberapa peringatan:

  1. hanya untuk PHP 5.3+ ( tapi itu bukan alasan yang bagus lagi )
  2. hanya mendukung tahun, bulan, hari, jam, menit dan detik (tanpa minggu)
  3. itu menghitung perbedaan dengan semua hari + di atas (Anda tidak bisa mendapatkan perbedaan hanya dalam beberapa bulan)

Untuk mengatasinya, saya memberi kode berikut (ditingkatkan dari jawaban @ 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;
}

Ini menjalankan dua loop; yang pertama berkaitan dengan interval relatif (tahun dan bulan) melalui brute-forcing, dan yang kedua menghitung interval absolut tambahan dengan aritmatika sederhana (jadi lebih cepat):

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);
}
Alix Axel
sumber
@PeterMortensen: Seharusnya berhasil, tapi saya tidak membuat jaminan. Tetapkan zona waktu Anda dan cobalah.
Alix Axel