Bagaimana cara membandingkan dua objek DateTime di PHP 5.2.8?

294

Setelah melihat dokumentasi PHP, dua metode DateTimeobjek berikut ini sepertinya akan menyelesaikan masalah saya:

Kedua metode ini ditandai dalam acara dokumenter sebagai tersedia dalam versi> = 5.3 (dan, tidak mengherankan, jika saya mencoba untuk memanggil mereka saya menemukan mereka tidak ada). Saya tidak dapat menemukan dokumentasi khusus untuk 5.2.8 jadi saya tidak yakin apakah ada metode yang setara dalam versi saya. Saya telah Googled masalah dan menemukan berbagai eklektik solusi, tidak ada yang menjawab kebutuhan saya sangat sederhana:

  • Bagaimana cara membandingkan dua objek DateTime?
  • Di mana saya dapat menemukan dokumen untuk versi PHP sebelumnya? Khususnya versi 5.2.8?

Untuk beberapa konteks, saya memiliki kode berikut:

$st_dt = new DateTime(verifyParam ('start_date'));
$end_dt = new DateTime(verifyParam ('end_date'));

// is the end date more ancient than the start date?
if ($end_dt < $start_dt) 

Rupanya tidak ada operator pembanding pada orang ini.

Edit

Rupanya asumsi saya benar-benar salah (terima kasih Milen untuk menggambarkan ini dengan sangat efektif). Ada operator perbandingan dan itu berfungsi dengan baik terima kasih. Terkadang saya benar-benar kehilangan kompiler. Bug ada dalam kode di atas, saya yakin Anda akan menemukannya jauh lebih cepat daripada yang saya lakukan :).

RedBlueThing
sumber
1
Mengenai kurangnya kompiler - atur "error_reporting" ke "E_ALL" dan Anda akan mendapatkan pemberitahuan seperti "Pemberitahuan: Variabel tidak terdefinisi: start_dt di ...".
Milen A. Radev
5
Juga, tolong, gunakan htmlentities di $_POSTvars Anda , atau anak kucing akan dibunuh.
Clement Herreman
2
Dan di mana letak kesalahannya? : p, saya juga melakukannya U_U. Terima kasih sebelumnya!
castarco
2
@castarco Saya menginisialisasi $ st_dt, tapi saya bandingkan dengan $ start_dt yang belum diinisialisasi. Periksa nama variabel Anda dan mungkin ikuti saran Milen dan atur error_reporting ke E_ALL untuk mendapatkan peringatan variabel yang tidak ditentukan. :)
RedBlueThing

Jawaban:

432

Berikut ini tampaknya mengonfirmasi bahwa ada operator perbandingan untuk kelas DateTime:

dev:~# php
<?php
date_default_timezone_set('Europe/London');

$d1 = new DateTime('2008-08-03 14:52:10');
$d2 = new DateTime('2008-01-03 11:11:10');
var_dump($d1 == $d2);
var_dump($d1 > $d2);
var_dump($d1 < $d2);
?>
bool(false)
bool(true)
bool(false)
dev:~# php -v
PHP 5.2.6-1+lenny3 with Suhosin-Patch 0.9.6.2 (cli) (built: Apr 26 2009 20:09:03)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
dev:~#
Milen A. Radev
sumber
7
Terima kasih Milen, sepertinya saya hanya perlu asumsi palsu saya dihapus dan tiba-tiba bug mencolok dalam kode saya menjadi jelas bagi saya.
RedBlueThing
2
Hmm, ini menarik. Mungkin pada titik tertentu kita akan dapat membebani operator di kelas yang ditentukan pengguna.
Ionuț G. Stan
1
Dari php.net/manual/en/language.operators.comparison.php Kelas bawaan dapat menentukan perbandingannya sendiri, kelas yang berbeda tidak dapat dibandingkan, kelas yang sama - membandingkan properti dengan cara yang sama seperti array (PHP 4), PHP 5 memiliki penjelasan sendiri
Saul
7
hati-hati ketika membandingkan datetime tanpa set jam dan satu dengan set waktu (konstruktor default)
max4ever
1
TiMESPLiNTER, saya percaya peringatannya adalah bahwa jika Anda hanya tertarik membandingkan tanggal, Anda mungkin mengabaikan fakta bahwa jamnya berbeda, dan dengan demikian dua DateTimes dengan tanggal yang sama tidak akan dibandingkan dengan yang sama ketika Anda yakin seharusnya. Anda dapat memperbaiki ini dengan secara eksplisit mengatur komponen waktu objek ke nol sebelum membandingkannya.
Jason
52

Dari dokumentasi resmi :

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); // false
var_dump($date1 < $date2); // true
var_dump($date1 > $date2); // false

Untuk versi PHP sebelum 5.2.2 (sebenarnya untuk versi apa pun), Anda dapat menggunakan diff .

$datetime1 = new DateTime('2009-10-11'); // 11 October 2013
$datetime2 = new DateTime('2009-10-13'); // 13 October 2013

$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days'); // +2 days
Roberto Alonso
sumber
3
Saya menemukan jawaban ini terbaik karena mengutip manual daripada hanya memeriksa perilaku dan mengasumsikan hasilnya seperti yang diharapkan. SO bukan tempat untuk menebak. Bravo Roberto.
cprn
3
@roberto DateTime :: diff hanya ditambahkan dalam PHP 5.3
NeXuS
30

Anda juga dapat membandingkan detik jaman:

$d1->format('U') < $d2->format('U')

Sumber: http://laughingmeme.org/2007/02/27/looking-at-php5s-datetime-and-datetimezone/ (artikel yang cukup menarik tentang DateTime)

Julien
sumber
16
Waspadalah yang formatmenghasilkan string , jadi itu perbandingan string. Ini bukan masalah setelah masa 1000000000 zaman (kira-kira 9 Sep 2001), tetapi jika Anda harus berurusan dengan tanggal sebelum itu, Anda mungkin mengalami masalah karena panjang nomor yang berbeda. Konversikan hasilnya ke angka (kurangi juga berfungsi), atau gunakan format yang benar-benar dapat disortir c.
MaxArt
1
@ MaxArt bisa tolong jelaskan masalah karena panjang string yang berbeda? Manual, mengenai string dalam konteks numerik: "Jika string tidak mengandung karakter '.', 'E', atau 'E' dan nilai numerik cocok dengan batas tipe integer (seperti yang didefinisikan oleh PHP_INT_MAX), string akan dievaluasi sebagai bilangan bulat. Dalam semua kasus lain itu akan dievaluasi sebagai pelampung. " Tanggal yang akan datang (sekitar tahun 2038) dapat meluap menandatangani bilangan bulat 32-bit, tapi apa masalahnya dengan tanggal yang lebih lama?
Adrian Günter
1
@ AdrianGünter Masalahnya adalah kita tidak akan berada dalam konteks numerik, tetapi kita akan berurusan dengan string . Angka, tetapi masih string. Jadi perbandingan string akan dibuat.
MaxArt
2
@ FrédéricMarchal Ya, saya memang mengetahui kemudian bahwa komentar saya sebelumnya ternyata salah. PHP memiliki cara yang benar-benar jahat untuk menangani kasus-kasus ini, tidak ada bahasa lain (seperti yang saya ketahui) dilemparkan ke angka ketika Anda memiliki dua string untuk membandingkan. Ini benar-benar mengacaukan kode Anda jika Anda benar-benar ingin membuat perbandingan leksikografis.
MaxArt
20

Jika Anda ingin membandingkan tanggal dan bukan waktu, Anda dapat menggunakan ini:

$d1->format("Y-m-d") == $d2->format("Y-m-d")
blablabla
sumber
5
Anda juga dapat mengatur waktu reset. $d1->setTime(0, 0, 0);
Athlan
3

Pada PHP 7.x, Anda dapat menggunakan yang berikut:

$aDate = new \DateTime('@'.(time()));
$bDate = new \DateTime('@'.(time() - 3600));

$aDate <=> $bDate; // => 1, `$aDate` is newer than `$bDate`
jens1o
sumber
0
$elapsed = '2592000';
// Time in the past
$time_past = '2014-07-16 11:35:33';
$time_past = strtotime($time_past);

// Add a month to that time
$time_past = $time_past + $elapsed;

// Time NOW
$time_now = time();

// Check if its been a month since time past
if($time_past > $time_now){
    echo 'Hasnt been a month';    
}else{
    echo 'Been longer than a month';
}
Kyle Coots
sumber
timestamp memiliki beberapa batasan, Anda mungkin ingin membaca stackoverflow.com/a/7229760/2652018
Steel Brain
Bagus untuk mengetahui! Ini hanya dimaksudkan sebagai cara sederhana untuk membandingkan waktu.
Kyle Coots
-1

Ini dapat membantu Anda.

$today = date("m-d-Y H:i:s");
$thisMonth =date("m");
$thisYear = date("y");
$expectedDate = ($thisMonth+1)."-08-$thisYear 23:58:00";


if (strtotime($expectedDate) > strtotime($today)) {
    echo "Expected date is greater then current date";
    return ;
} else
{
 echo "Expected date is lesser then current date";
}
Tarun Gupta
sumber
timestamp memiliki beberapa batasan, Anda mungkin ingin membaca stackoverflow.com/a/7229760/2652018
Steel Brain
@SteelBrain menurut Anda batasan timestamp mengganggu kode di atas yang memiliki semua waktu tanggal saat ini, Silakan baca kode lagi, Ini pada dasarnya memeriksa cowok $ expectedDate yang akan selalu ada di bulan berjalan. Saya tidak berpikir jadi kita harus memikirkan batasan cap waktu di sini dalam kasus ini.
Tarun Gupta
Saya tahu, tapi ini bukan cara yang disarankan, (saya tidak mengundurkan diri :-))
Steel Brain
Bisakah Anda menyarankan cara yang disarankan.
Tarun Gupta
tentu, $today = new DateTime("now"); $time = DateTime::createFromFormat('d-m-Y',"26-October-1998"); if ($today > $time){echo "today is greater";}else{echo "other time is greater";}ceria.
Steel Brain