Jak mogę porównać dwie daty w PHP?

125

Jak mogę porównać dwie daty w PHP?

Data jest przechowywana w bazie danych w następującym formacie

2011-10-2

Gdybym chciał porównać dzisiejszą datę z datą w bazie danych, aby zobaczyć, która z nich jest większa, jak mam to zrobić?

Próbowałem tego,

$today = date("Y-m-d");
$expire = $row->expireDate //from db

if($today < $expireDate) { //do something; }

ale tak naprawdę to nie działa. Jaki jest inny sposób na zrobienie tego?

Sarmen B.
źródło
Przypisz daty db do obiektu DateTime, a następnie porównaj te obiekty. Możesz znaleźć fajny przykład na stackoverflow.com/questions/961074/ ...
Peter

Odpowiedzi:

80

w bazie danych data wygląda następująco: 2011-10-2

Zapisz go w formacie RRRR-MM-DD, a wtedy porównanie ciągów zadziała, ponieważ „1”> „0” itd.

Mateusz
źródło
2
ale co jeśli wyglądają tak, 2011-10-02 i 2012-02-10, dla porównania miesięcznego 1> 0, ale 2011-10-02 <2012-02-10
dav
14
@Davo, porównanie kończy się na pierwszym innym znaku. W tym przypadku czwarta cyfra „1” <„2”, więc otrzymasz oczekiwany wynik.
Matthew,
1
Przepraszam :), nie był wystarczająco ostrożny.
dav
czy poniższe zadziała 2016-03-27 11:59:47 ::: 2016-03-14 10:30:00?
shorif2000
221

Jeśli wszystkie twoje daty są późniejsze niż 1 stycznia 1970, możesz użyć czegoś takiego:

$today = date("Y-m-d");
$expire = $row->expireDate; //from database

$today_time = strtotime($today);
$expire_time = strtotime($expire);

if ($expire_time < $today_time) { /* do Something */ }

Jeśli używasz PHP 5> = 5.2.0, możesz użyć klasy DateTime:

$today_dt = new DateTime($today);
$expire_dt = new DateTime($expire);

if ($expire_dt < $today_dt) { /* Do something */ }

Albo coś w tym stylu.

Hugo Peixoto
źródło
O ile dobrze pamiętam, obawa 1st of January of 1970dotyczy tylko starszych wersji PHP działających w systemie Windows i nigdy nie była problemem na Uniksie.
Álvaro González
Podoba mi się ta odpowiedź. To świetny wybór do konwersji dat na strtotime ()
Erich García
2
Czy nie brzmiałoby to teraz „Jeśli wszystkie wasze daty są późniejsze niż 1 stycznia 1970 r.” I „przed 2038 r.”? uważaj na błąd Y2k38. strtotimezwróci wartość false dla dłuższych dat. stackoverflow.com/questions/2012589/…
blamb
Zwróć uwagę, że ta DateTimemetoda jest metodą preferowaną. Ten obiekt może zrobić znacznie więcej niż strtotimekiedykolwiek.
Machavity
new DateTime('now')działa również, aby pobrać dzisiejszą datę
Breith
23

Aby uzupełnić udzielone już odpowiedzi, zobacz następujący przykład:

$today = new DateTime('');
$expireDate = new DateTime($row->expireDate); //from database



if($today->format("Y-m-d") < $expireDate->format("Y-m-d")) { 
    //do something; 
}

Aktualizacja: Lub po prostu użyj starej szkoły date () :

if(date('Y-m-d') < date('Y-m-d', strtotime($expire_date))){
    //echo not yet expired! 
}   
d.raev
źródło
1
Data jest funkcją, a nie klasą / konstruktorem.
spdionis
2
@spdionis dzięki za komentarz, zmieniłem wielką literę, aby usunąć możliwe nieporozumienia.
d.raev
6

Nie zrobiłbym tego z PHP. Baza danych powinna wiedzieć, jaki dzień jest dzisiaj. (Użyj na przykład MySQL-> NOW ()), więc porównanie w zapytaniu będzie bardzo łatwe i zwrócenie wyniku, bez żadnych problemów, w zależności od użytych typów dat

SELECT IF(expireDate < NOW(),TRUE,FALSE) as isExpired FROM tableName
Dr Molle
źródło
dzięki, ale faktycznie używam date (), nie przechowuję dzisiejszej daty w bazie danych
Sarmen B.
4
Ale przechowujesz expireDate w bazie danych. Porównaj tę datę z NOW ()
dr Molle
4
$today = date('Y-m-d');//Y-m-d H:i:s
$expireDate = new DateTime($row->expireDate);// From db 
$date1=date_create($today);
$date2=date_create($expireDate->format('Y-m-d'));
$diff=date_diff($date1,$date2);

//echo $timeDiff;
if($diff->days >= 30){
    echo "Expired.";
}else{
    echo "Not expired.";
}
Atif Mahmood
źródło
2

Oto sposób, w jaki sposób uzyskać różnicę między dwiema datami w minutach.

// set dates
$date_compare1= date("d-m-Y h:i:s a", strtotime($date1));
// date now
$date_compare2= date("d-m-Y h:i:s a", strtotime($date2));

// calculate the difference
$difference = strtotime($date_compare1) - strtotime($date_compare2);
$difference_in_minutes = $difference / 60;

echo $difference_in_minutes;
Syno
źródło
Pytanie dotyczy porównania 2 dat - twoją odpowiedzią jest dodanie mnóstwa dodatkowych rzeczy (np. Ustawienie statusu online / offline), które nie są konieczne jako odpowiedź na pytanie. Część Twojej odpowiedzi, w której ma miejsce porównanie, jest praktycznie taka sama, jak już istniejąca odpowiedź tutaj .
crazyloonybin
Zaktualizowałem pytanie, zamieściłem złą odpowiedź w niewłaściwym pytaniu ^^;) To nie to samo, co odpowiedź, po prostu dodam mój wkład, jak je porównać i uzyskać różnicę w minutach.
Syno
1
Usunąłem mój głos negatywny z powodu twojej aktualizacji, teraz wygląda znacznie lepiej :)
crazyloonybin
2

Możesz konwertować daty na znaczniki czasu UNIX i porównywać różnice między nimi w sekundach.

$today_date=date("Y-m-d");
$entered_date=$_POST['date'];
$dateTimestamp1 = strtotime($today_date);
$dateTimestamp2 = strtotime($entered_date);
$diff= $dateTimestamp1-$dateTimestamp2;
//echo $diff;
if ($diff<=0)
   {
     echo "Enter a valid date";
   }
Shruthi reddy
źródło
0

Ja też miałem ten problem i rozwiązuję go poprzez:

$today = date("Ymd");
$expire = str_replace('-', '', $row->expireDate); //from db

if(($today - $expire) > $NUMBER_OF_DAYS) 
{ 
    //do something; 
}
PiotrK
źródło
Dlaczego ta technika działa, należy wyjaśnić w odpowiedzi.
mickmackusa
Odpowiedz na opublikowane pytanie OP, a nie jak rozwiązałeś swój własny, unikalny scenariusz.
mickmackusa
0

Oto moje omówienie, jak uzyskać różnicę w dniach między dwiema datami za pomocą PHP. Zwróć uwagę na użycie znaku „!” w formacie, aby odrzucić część czasową dat, dzięki informacjom z DateTime createFromFormat bez czasu .

$today = DateTime::createFromFormat('!Y-m-d', date('Y-m-d'));
$wanted = DateTime::createFromFormat('!d-m-Y', $row["WANTED_DELIVERY_DATE"]);
$diff = $today->diff($wanted);
$days = $diff->days;
if (($diff->invert) != 0) $days = -1 * $days;
$overdue = (($days < 0) ? true : false);
print "<!-- (".(($days > 0) ? '+' : '').($days).") -->\n";
nwsmith
źródło
-1

Znalazłem odpowiedź na blogu i jest to tak proste, jak:

strtotime(date("Y"."-01-01")) -strtotime($newdate))/86400

I otrzymasz dni między 2 datami.

kooli
źródło
Wydaje się, że rozwiązuje to inny problem. Proszę odpowiedzieć tylko na pytanie zadane przez PO.
mickmackusa
-1

Działa to dzięki logice porównywania ciągów PHP. Po prostu możesz sprawdzić ...

if ($startdate < $date) {// do something} 
if ($startdate > $date) {// do something}

Obie daty muszą mieć ten sam format. Cyfry muszą być wypełnione zerami po lewej stronie i uporządkowane od najbardziej znaczących do najmniej znaczących. Y-m-di Y-m-d H:i:sspełniają te warunki.

sanjyot
źródło
1
d-m-Ynie zadziała ... Y-m-d(z początkowym zerem jak 2016-05-08) zadziała. Sprawdź te daty w d-m-Yformacie 01-10-2016i 20-02-2016porównując jako ciągi 0 <2, przestanie porównywać, ale niepoprawnie ...
Arxeiss
Oto dowód, że technika nie będzie w stanie prawidłowo porównać daty PO przeciw dniu dzisiejszym: 3v4l.org/SNHKT
mickmackusa
PO ma inny format daty. wygląda data 2011-10-2.
mickmackusa
-1

Jeśli chcesz, aby data ($ date) wygasła w pewnym przedziale, na przykład data wygaśnięcia tokena podczas resetowania hasła, oto jak możesz to zrobić:

$date = $row->expireDate;

$date->add(new DateInterval('PT24H')); // adds 24 hours

$now = new \DateTime();

if($now < $date) { /* expired after 24 hours */ }

Ale w twoim przypadku możesz wykonać porównanie w następujący sposób:

$today = new DateTime('Y-m-d');

$date = $row->expireDate;

if($today < $date) { /* do something */ }
faye.babacar78
źródło
Ta odpowiedź ignoruje pierwotnie opublikowane pytanie. Proszę skorzystać z przykładowych danych dostarczonych przez PO.
mickmackusa
Nie jest to dokładnie to, o co facet prosi o pomoc, ale pomyślałem, że ten sposób może pomóc, jeśli zrozumie się zasady.
faye.babacar78
Rozumiem zasady, ale ten kod nie odpowiada na zadane pytanie. Ta strona jest już przepełniona błędnymi i niepowiązanymi odpowiedziami - to tylko dezorientuje badaczy i marnuje ich czas. Staram się szukać naukowców.
mickmackusa
Myślę, że nie jest to takie trudne, mógł użyć klasy DateTime () zamiast funkcji date (). Odpowiedź, którą umieściłem powyżej, ma na celu przedstawienie naukowcom pomysłów.
faye.babacar78
1
Przestanę się powtarzać i wycofam się z tej dyskusji. Drugie co do wielkości rozwiązanie ( stackoverflow.com/a/3847762/2943403 ) pokazuje strasznie prosty (nie do pobicia) sposób tworzenia dwóch obiektów datetime. Nie mam pojęcia, co robi twoja magiczna requestDate()metoda - nigdzie o niej nie ma mowy. Nie użyłbym twojej odpowiedzi ani nie poleciłbym badaczowi skorzystania z twojego rozwiązania. Nie przewiduję zmiany mojego głosu.
mickmackusa
-2

Przede wszystkim spróbuj nadać aktualny format daty i czasu serwera w żądanym formacie:

  1. Uzyskaj aktualną datę i godzinę

    $ current_date = getdate ();

  2. Oddzielną datę i godzinę, aby zarządzać nimi według własnego uznania:

$ current_date_only = $ current_date [rok] .'- '. $ current_date [mon] .'-'. $ current_date [mday]; $ current_time_only = $ current_date ['hours']. ':'. $ current_date ['minutes']. ':'. $ current_date ['seconds'];

  1. Porównaj to w zależności od tego, czy używasz daty donly czy datetime w swojej bazie danych:

    $ dzisiaj = $ current_date_only. ' '. $ current_time_only;

    lub

    $ dzisiaj = $ current_date_only;

    if ($ dzisiaj <$ expireDate)

mam nadzieję, że to pomoże

ernestoloredo
źródło
Ta odpowiedź nie jest próbą rozwiązania pierwotnego pytania. OP nie interesuje się godzinami, minutami ani sekundami.
mickmackusa