PHP 5.2.8'de iki DateTime nesnesini nasıl karşılaştırabilirim?


294

PHP belgelerine bir göz atın, DateTimenesnenin aşağıdaki iki yöntem her ikisi de benim sorunumu çözmek gibi görünüyor:

Her iki yöntem de doco'da > = 5.3 sürümünde olarak işaretlenmiştir (ve şaşırtıcı bir şekilde, onları aramaya çalışırsam, var olmadığını buluyorum). 5.2.8 için belirli bir belge bulamıyorum, bu yüzden sürümümde eşdeğer yöntemler olup olmadığından emin değilim. Ben var google'dan sorunu ve benim çok basit gereksinimlerini cevap hiçbiri çözümleri, eklektik bir dizi bulundu:

  • İki DateTime nesnesini nasıl karşılaştırabilirim?
  • Önceki PHP sürümleri için doco'yu nerede bulabilirim? Özellikle sürüm 5.2.8?

Bazı bağlamlar için, aşağıdaki kod var:

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

Görünüşe göre bu adam üzerinde bir karşılaştırma operatörü yok.

Düzenle

Görünüşe göre varsayımlarım tamamen yanlıştı (bunu çok etkili bir şekilde gösterdiği için Milen'e teşekkürler). Bir karşılaştırma operatörü var ve iyi çalışıyor teşekkürler. Bazen bir derleyiciyi gerçekten özlüyorum. Hata yukarıdaki kodda, eminim benden çok daha hızlı bulacaksınız :).


1
Derleyici eksikliğiyle ilgili olarak "error_reporting" ifadesini "E_ALL" olarak ayarlayın ve "Uyarı: Tanımsız değişken: start_dt in ..." gibi bildirimler alırsınız.
Milen A.Radev

5
Ayrıca, lütfen çeşitlerinizde htmlentities kullanın $_POST, yoksa yavru kedi öldürülecektir.
Clement Herreman

2
Ve hata nerede? : p, ben de yapıyorum U_U. Şimdiden teşekkürler!
castarco

2
@castarco $ st_dt başlatıyorum, ancak tamamlanmamış $ start_dt ile karşılaştırıyorum. Değişken adlarınızı kontrol edin ve Milen'in önerisini izleyin ve tanımlanmamış değişken uyarıları almak için error_porting öğesini E_ALL olarak ayarlayın. :)
RedBlueThing

Yanıtlar:


433

Aşağıdakiler, DateTime sınıfı için karşılaştırma işleçleri olduğunu doğrulamaktadır:

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:~#

7
Teşekkürler Milen, görünüşe göre yanlış varsayımlarımın kaldırılmasına ihtiyacım vardı ve aniden kodumdaki göze çarpan hata benim için belirginleşti.
RedBlueThing

2
Hmm, bu ilginç. Belki bir noktada kullanıcı tanımlı sınıflardaki operatörleri aşırı yükleyebiliriz.
Ionuț G. Stan

1
Kaynaktan php.net/manual/en/language.operators.comparison.php Dahili sınıfları kendi karşılaştırma tanımlayabilir, farklı sınıflar sınıfın aynı sınıf - karşılaştırma özellikleri diziler (PHP 4) ile aynı şekilde, PHP 5'in sahip kendi açıklama
Saul

7
saat ve saat ayarlanmamış bir tarih saatini karşılaştırırken dikkat edin (varsayılan oluşturucu)
max4ever 19:12

1
TiMESPLiNTER, uyarının sadece tarihleri ​​karşılaştırmakla ilgileniyorsanız, saatlerin farklı olduğu gerçeğini göz ardı edebileceğinizi ve bu nedenle DateTimeaynı tarihe sahip iki saniyenin, gerektiğine inandığınızda eşit olarak karşılaştırılmayacağına inanıyorum. Nesnenin zaman bileşenlerini karşılaştırmadan önce sıfıra ayarlayarak bunu düzeltebilirsiniz.
Jason

52

Gönderen Resmi belgelerin :

PHP 5.2.2'den itibaren, DateTime nesneleri karşılaştırma işleçleri kullanılarak karşılaştırılabilir .

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

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

5.2.2'den önceki PHP sürümleri için (aslında herhangi bir sürüm için) diff kullanabilirsiniz .

$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

3
Bu cevabı en iyi buluyorum çünkü sadece davranışı kontrol etmek ve sonucun beklendiği gibi olduğunu varsaymak yerine el kitabından alıntı yapıyor. SO tahmin için bir yer değil. Bravo Roberto.
cprn

3
@roberto DateTime :: diff sadece PHP 5.3'te eklendi
NeXuS

30

Ayrıca dönem saniye karşılaştırabilirsiniz:

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

Kaynak: http://laughingmeme.org/2007/02/27/looking-at-php5s-datetime-and-datetimezone/ (DateTime hakkında oldukça ilginç bir makale)


16
formatBir dize üreten dikkat edin , bu yüzden bir dize karşılaştırma. 1000000000 döneminden sonra neredeyse bir sorun değil (kabaca 9 Eylül 2001), ancak bundan önceki tarihlerle uğraşmak zorunda kalırsanız, farklı sayı uzunlukları nedeniyle sorunlara maruz kalabilirsiniz. Sonuçları sayılara dönüştürün (çıkartmak da işe yarar) veya gerçekten sıralanabilir bir format kullanın c.
MaxArt

1
@MaxArt, farklı dize uzunluklarından kaynaklanan sorunları biraz açıklayabilir misiniz? Sayısal bağlamdaki dizelerle ilgili el kitabı: "Dize '.', 'E' veya 'E' karakterlerini içermiyorsa ve sayısal değer tamsayı türü sınırlarına (PHP_INT_MAX ile tanımlandığı gibi) uyuyorsa, dize diğer tüm durumlarda bir kayan nokta olarak değerlendirilir. " Gelecek tarihler (2038 civarı) imzalı 32 bit tam sayıları aşabilir, ancak eski tarihlerle ilgili sorun nedir?
Adrian Günter

1
@ AdrianGünter Sorun, sayısal bir bağlamda olmayacağımız, ancak dizelerle ilgileneceğimizdi . Sayısal, ancak yine de dizeler. Böylece bir dize karşılaştırması yapılır.
MaxArt


2
@ FrédéricMarchal Evet, gerçekten daha sonradan önceki yorumumun aslında yanlış olduğunu öğrendim. PHP bu vakaları tedavi etmek için gerçekten kötü bir yol var, başka bir dil (bildiğim gibi) karşılaştırmak için iki dizeniz olduğunda sayılara çevirir. Gerçekten sözlükbilimsel bir karşılaştırma yapmak istiyorsanız, kodunuzu gerçekten vidalar.
MaxArt

20

Tarihleri ​​değil, tarihleri ​​karşılaştırmak istiyorsanız, bunu kullanabilirsiniz:

$d1->format("Y-m-d") == $d2->format("Y-m-d")

5
Sıfırlama zamanını da ayarlayabilirsiniz. $d1->setTime(0, 0, 0);
Athlan

3

PHP 7.x'ten itibaren aşağıdakileri kullanabilirsiniz:

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

$aDate <=> $bDate; // => 1, `$aDate` is newer than `$bDate`

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

damgası Bunu okumak isteyebilirsiniz, bir bazı sınırlamaları vardır stackoverflow.com/a/7229760/2652018
Çelik Beyin

Bilmek güzel! Bu sadece zamanları karşılaştırmanın basit bir yoluydu.
Kyle Coots

-1

Bu size yardımcı olabilir.

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

damgası Bunu okumak isteyebilirsiniz, bir bazı sınırlamaları vardır stackoverflow.com/a/7229760/2652018
Çelik Beyin

@SteelBrain, zaman damgası sınırlamasının tüm geçerli tarih saatine sahip olan kodun üstünde olduğunu düşünüyor musunuz, Lütfen kodu tekrar okuyun, Temel olarak her zaman geçerli ay içinde olacak $ beklenilen tarih olup olmadığını kontrol edin. Bence bu durumda zaman damgası sınırlamasını düşünmeliyiz.
Tarun Gupta

Biliyorum, ama bu tavsiye edilen bir yol değil, (Ben downvote :-))
Steel Brain

Tavsiye edilen bir yol önerebilir misiniz?
Tarun Gupta

tabi, $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";}şerefe.
Steel Brain
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.