Użyj tego dla starszego kodu (PHP <5.3). Aktualne rozwiązanie znajduje się w odpowiedzi jurki poniżej
Możesz użyć strtotime (), aby przekonwertować dwie daty na czas uniksowy, a następnie obliczyć liczbę sekund między nimi. Na tej podstawie łatwo jest obliczyć różne okresy.
Edycja: Oczywiście preferowanym sposobem na zrobienie tego jest opisany poniżej przez jurka. Mój kod jest ogólnie zalecany tylko wtedy, gdy nie masz PHP 5.3 lub nowszego.
Kilka osób w komentarzach zauważyło, że powyższy kod jest jedynie przybliżeniem. Nadal uważam, że dla większości celów jest to w porządku, ponieważ użycie zakresu służy raczej do określenia, ile czasu minęło lub pozostało, niż do zapewnienia precyzji - jeśli chcesz to zrobić, po prostu podaj datę.
Mimo to postanowiłem zająć się skargami. Jeśli naprawdę potrzebujesz dokładnego zakresu, ale nie masz dostępu do PHP 5.3, użyj poniższego kodu (powinien również działać w PHP 4). Jest to bezpośredni port kodu, którego PHP używa wewnętrznie do obliczania zakresów, z tym wyjątkiem, że nie bierze pod uwagę czasu letniego. Oznacza to, że jest wyłączony najwyżej o godzinę, ale poza tym powinien być poprawny.
<?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)));
Jeśli używasz klasy DateTime, możesz wybrać $ date-> format ('U'), aby uzyskać uniksowy znacznik czasu.
Jon Cram,
4
To nieprawda, jeśli masz do czynienia z czasem letnim / zimowym. W tym konkretnym przypadku, gdy dostosowujesz czas letni / zimowy, jeden dzień to 23 lub 25 godzin.
Arno,
4
Cóż, ten sam argument można wysunąć na lata przestępne. Nie bierze tego pod uwagę. Mimo to nie jestem przekonany, czy w ogóle chcesz to wziąć pod uwagę, ponieważ omawiamy tutaj zakres. Semantyka dla zakresu jest nieco inna niż dla daty bezwzględnej.
Emil H
9
Ta funkcja jest nieprawidłowa. Jest to dobre dla przybliżenia, ale niepoprawne dla dokładnych zakresów. Po pierwsze, zakłada się, że jest 30 dni w miesiącu, co oznacza, że będzie miała tę samą różnicę dni między 1 lutego a 1 marca, jak w przypadku 1 lipca do 1 sierpnia (niezależnie od roku przestępnego).
enobrev
1
W PHP zmienne referencyjne znajdują się w podpisie funkcji, a nie w wywołaniu. Przenieś wszystko &do podpisów.
Paul Tarjan
909
Sugeruję użycie obiektów DateTime i DateInterval.
$date1 =newDateTime("2007-03-24");
$date2 =newDateTime("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 ";
+1 DateTime poprawnie obsługuje lata przestępne i strefy czasowe, a na półce jest dobra książka: phparch.com/books/…
hakre
3
Czy istnieje metoda, która podaje całkowitą liczbę sekund między dwoma DateTimes? (bez dodawania składników, to znaczy)
potatoe
1
@Panique $ przedział-> dni i $ przedział-> d to różne miary. Twój komentarz powyżej jest słuszny „pokazuje całkowitą liczbę dni (
niepodzieloną
1
@potatoe Prawdopodobnie chcesz $date2->format('U') - $date1->format('U').
Paulo Freitas,
3
zauważ, że występuje błąd, w którym DateInterval ma niepoprawną właściwość dni ( zawsze 6015 ) w systemie Windows w niektórych wersjach PHP: bugs.php.net/bug.php?id=51184 (zapoznaj się z komentarzami w celu naprawy / obejścia)
Pim Schaaf
73
Najlepszym sposobem działania jest użycie obiektów PHP DateTime(i DateInterval). Każda data jest kapsułkowana w DateTimeobiekcie, a następnie można wprowadzić różnicę między nimi:
DateTimeObiekt zaakceptuje każdy format strtotime()będzie. Jeśli potrzebny jest jeszcze bardziej szczegółowy format daty, DateTime::createFromFormat()można go użyć do utworzenia DateTimeobiektu.
Po utworzeniu instancji obu obiektów odejmujesz jeden od drugiego za pomocą DateTime::diff().
$difference = $first_date->diff($second_date);
$differenceteraz zawiera DateIntervalobiekt z informacją o różnicy. A var_dump()wygląda to tak:
Mamy problem, wymieniamy first_date na second_date i otrzymujemy ten sam wynik? Dlaczego nie powiesz 0 dni 0 godzin 0 minut 0 sekund lub tylko 0. Przykład: 2012-11-30 17:03:30 - 2012-12-21 00:00:00 i 2012-12-21 00:00:00 - 30.11.2012 17:03:30 uzyskaj ten sam wynik.
EgoistDeveloper
Ponieważ diff daje różnicę między tymi dwoma czasami. Różnica nie wynosi 0, niezależnie od tego, która data nastąpi później.
Duch Madary
1
To naprawdę dobra odpowiedź, ponieważ zapewnia wyraźną funkcję, którą można wywołać z dowolnego miejsca w bazie kodu bez dużej ilości czasu. Inne odpowiedzi pozwalają upuszczać cielęta w locie, które odnoszą się do objawów, a nie rozwiązują problem ... Jedynym elementem, który dodałem (i prawie wszystkie inne posty tego nie obejmują) jest pluralizacja elementów z przedziałami $ jeśli więcej niż 1.
I jest okropnym rozwiązaniem, chyba że jesteś zmuszony użyć strasznie przestarzałej wersji PHP ...
rdlowrey
2
Nie tak SUCHO . Na przykład 60 * 60 * 24 powtarza się 15 razy. Niech żyje ponowne użycie kopiuj-wklej!
Peter Mortensen
Co z latami przestępnymi? Rok średnio nie wynosi 365 dni.
Peter Mortensen
Ten kod zakłada, że miesiąc wynosi średnio 30 dni. Nawet zakładając 365 dni w roku, średni miesiąc to 365/12 = 30,42 dni (w przybliżeniu).
Peter Mortensen
18
Spójrz na poniższy link. To najlepsza odpowiedź, jaką do tej pory znalazłem .. :)
function dateDiff ($d1, $d2){// Return the number of days between the two dates: return round(abs(strtotime($d1)- strtotime($d2))/86400);}// end function dateDiff
Nie ma znaczenia, która data jest wcześniejsza czy późniejsza, gdy podasz parametry daty. Funkcja wykorzystuje wartość bezwzględną ABS () PHP, aby zawsze zwracać liczbę dodatnią jako liczbę dni między dwiema datami.
Pamiętaj, że liczba dni między dwiema datami NIE obejmuje obu dat. Jeśli więc szukasz liczby dni reprezentowanych przez wszystkie daty między wprowadzonymi datami włącznie, musisz dodać jeden (1) do wyniku tej funkcji.
Na przykład różnica (zwrócona przez powyższą funkcję) między 2013-02-09 a 2013-02-14 wynosi 5. Ale liczba dni lub dat reprezentowana przez zakres dat 2013-02-09 - 2013-02- 14 to 6.
Pytanie dotyczyło różnicy jako liczby lat, miesięcy i dni, a nie całkowitej liczby dni.
Peter Mortensen
14
Głosowałem za Jurka „s odpowiedź jak to mój ulubiony, ale mam wersję pre-php.5.3 ...
Odkryłem, że pracuję nad podobnym problemem - w ten sposób przede wszystkim dotarłem do tego pytania - ale potrzebowałem tylko różnicy godzin. Ale moja funkcja rozwiązała to całkiem nieźle i nie mam nigdzie w mojej własnej bibliotece, aby przechowywać ją tam, gdzie nie zostanie zgubiona i zapomniana, więc ... mam nadzieję, że jest to przydatne dla kogoś.
Stąd otrzymałem oryginalny pomysł , który zmodyfikowałem dla moich zastosowań (i mam nadzieję, że moja modyfikacja pojawi się również na tej stronie).
Możesz bardzo łatwo usunąć interwały, których nie chcesz (powiedz „tydzień”), usuwając je z $aIntervalstablicy lub dodając $aExcludeparametr, lub po prostu odfiltrowując je, gdy wypisujesz ciąg.
Niestety nie zwraca to tego samego co DateInterval z powodu przepełnienia roku / miesiąca.
Stephen Harris
2
@StephenHarris: Nie testowałem tego, ale czytając kod jestem pewien, że powinien zwrócić ten sam wynik - pod warunkiem, że usuniesz weekindeks w $aIntervals(ponieważ DateDiffnigdy tego nie używa).
Alix Axel,
Jest to świetne rozwiązanie do wyszukiwania dat, które występują w każdym przedziale między dwiema datami.
betweenbrain 18.10.19
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);?>
Pytanie dotyczyło różnicy liczby lat , miesięcy i dni . Daje to różnicę jako całkowitą liczbę dni.
Peter Mortensen
11
Nie wiem, czy używasz frameworka PHP, czy nie, ale wiele frameworków PHP ma biblioteki daty / godziny i pomocniki, które pomogą Ci powstrzymać się od ponownego wynalezienia koła.
Na przykład CodeIgniter ma timespan()funkcję. Po prostu wprowadź dwa znaczniki czasu Unix, a automatycznie wygeneruje taki wynik:
wydaje się nie działać. Dostaję datę na początku ery znaczników czasu.
Sirber,
Ważne jest, aby zrozumieć, że musisz zrobić, $my_t["year"] -= 1970aby uzyskać prawidłową liczbę lat. Należy również odjąć swój różnicę godziny od GMT, aby uzyskać prawo godzin. Musisz również odjąć 1 od miesiąca i daty.
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;}
Czy „strtotime („ + 1 rok ”, $ date1)” uwzględnia lata przestępne?
Peter Mortensen
6
To moja funkcja. Wymagane PHP> = 5.3.4. Używa klasy DateTime. Bardzo szybko, szybko i może zrobić różnicę między dwiema datami, a nawet tak zwanym „czasem od”.
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 maintenantif(empty($To)=== TRUE){
$To = time();}# On va s'assurer que $From est numériqueif(is_int($From)=== FALSE){
$From = strtotime($From);};# On va s'assurer que $To est numériqueif(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 =newDateTime(@date('Y-m-d H:i:s', $From),newDateTimeZone('GMT'));
$To =newDateTime(@date('Y-m-d H:i:s', $To),newDateTimeZone('GMT'));# On va calculer la différence entre $From et $Toif(($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 maintenantif($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;}}
Spróbuje to wykryć, czy podany został znacznik czasu, a także zwróci przyszłe daty / godziny jako wartości ujemne:
<?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 =newDateTime(date('Y-m-d H:i:s', $$start_time_var));
$now =newDateTime(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;}elseif($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;}
„jeśli” data jest przechowywana w MySQL, łatwiej jest mi wykonać obliczenie różnicy na poziomie bazy danych ... Następnie na podstawie danych wyjściowych Dzień, Godzina, Min, Sek, parsowanie i wyświetlanie wyników odpowiednio ...
Znalazłem twój artykuł na następnej stronie, która zawiera szereg odniesień do obliczeń daty i godziny w PHP .
Oblicz różnicę między dwiema datami (i czasem) za pomocą PHP. Następująca strona zawiera szereg różnych metod (łącznie 7) do wykonywania obliczeń daty / godziny za pomocą PHP, w celu ustalenia różnicy czasu (godziny, munity), dni, miesięcy lub lat między dwiema datami.
Możesz także użyć następującego kodu, aby zwrócić różnicę daty o ułamki zaokrąglone w górę $ date1 = $ duedate; // przypisanie terminu echo $ date2 = data („Ymd”); // bieżąca data $ ts1 = strtotime ($ date1); $ ts2 = strtotime ($ date2); $ seconds_diff = $ ts1 - $ ts2; echo $ datediff = ceil (($ seconds_diff / 3600) / 24); // powrót za kilka dni
Jeśli użyjesz metody podłogowej php zamiast sufitu, zwróci ci ona okrągłą frakcję w dół. Sprawdź różnicę tutaj, czasami, jeśli strefa czasowa serwerów pomostowych jest inna niż strefa czasowa witryny na żywo, w takim przypadku możesz uzyskać inne wyniki, więc odpowiednio zmień warunki.
Miałem ten sam problem z PHP 5.2 i rozwiązałem go za pomocą MySQL. Może nie być dokładnie tym, czego szukasz, ale to załatwi sprawę i zwróci liczbę dni:
Ponieważ wszyscy publikują próbki kodu, oto inna wersja.
Chciałem, aby funkcja wyświetlała różnice od sekund do lat (tylko jedna jednostka). W przypadku okresów dłuższych niż 1 dzień chciałem, aby kumulował się o północy (10 rano w poniedziałek widziany od 9 rano w środę jest 2 dni temu, a nie 1). I dla okresów powyżej miesiąca chciałem, aby rolowanie miało miejsce tego samego dnia miesiąca (w tym dla miesięcy 30 i 31 dni przestępnych).
Oto co wymyśliłem:
/**
* 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';}
Ta odpowiedź jest tak samo błędna jak odpowiedź Khaldonno. Zakłada (przypadek 10), że rok ma 365 dni (co czwarty rok ma 366 dni (z wyjątkiem reguł 100-letnich / 400-letnich dla kalendarza gregoriańskiego)) i że miesiąc ma 30 dni (około 30,42 dni w latach bez przestępstwa). Nawet przy lepszych stałych jest to tylko poprawne średnio, niekoniecznie poprawne dla dwóch konkretnych dat.
Peter Mortensen,
3
Bardzo prosta:
<?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>";?>
Proszę sprawdzić poniższy link, aby uzyskać szczegółowe informacje:
Działa dwie pętle; pierwszy dotyczy względnych przedziałów (lat i miesięcy) za pomocą brutalnego wymuszania, a drugi oblicza dodatkowe przedziały bezwzględne za pomocą prostej arytmetyki (więc jest szybszy):
Odpowiedzi:
Możesz użyć strtotime (), aby przekonwertować dwie daty na czas uniksowy, a następnie obliczyć liczbę sekund między nimi. Na tej podstawie łatwo jest obliczyć różne okresy.
Edycja: Oczywiście preferowanym sposobem na zrobienie tego jest opisany poniżej przez jurka. Mój kod jest ogólnie zalecany tylko wtedy, gdy nie masz PHP 5.3 lub nowszego.
Kilka osób w komentarzach zauważyło, że powyższy kod jest jedynie przybliżeniem. Nadal uważam, że dla większości celów jest to w porządku, ponieważ użycie zakresu służy raczej do określenia, ile czasu minęło lub pozostało, niż do zapewnienia precyzji - jeśli chcesz to zrobić, po prostu podaj datę.
Mimo to postanowiłem zająć się skargami. Jeśli naprawdę potrzebujesz dokładnego zakresu, ale nie masz dostępu do PHP 5.3, użyj poniższego kodu (powinien również działać w PHP 4). Jest to bezpośredni port kodu, którego PHP używa wewnętrznie do obliczania zakresów, z tym wyjątkiem, że nie bierze pod uwagę czasu letniego. Oznacza to, że jest wyłączony najwyżej o godzinę, ale poza tym powinien być poprawny.
źródło
&
do podpisów.Sugeruję użycie obiektów DateTime i DateInterval.
czytaj więcej php DateTime :: diff manual
Z instrukcji:
źródło
$date2->format('U') - $date1->format('U')
.Najlepszym sposobem działania jest użycie obiektów PHP
DateTime
(iDateInterval
). Każda data jest kapsułkowana wDateTime
obiekcie, a następnie można wprowadzić różnicę między nimi:DateTime
Obiekt zaakceptuje każdy formatstrtotime()
będzie. Jeśli potrzebny jest jeszcze bardziej szczegółowy format daty,DateTime::createFromFormat()
można go użyć do utworzeniaDateTime
obiektu.Po utworzeniu instancji obu obiektów odejmujesz jeden od drugiego za pomocą
DateTime::diff()
.$difference
teraz zawieraDateInterval
obiekt z informacją o różnicy. Avar_dump()
wygląda to tak:Aby sformatować
DateInterval
obiekt, musimy sprawdzić każdą wartość i wykluczyć ją, jeśli wynosi 0:Teraz pozostaje tylko wywołać naszą funkcję na
$difference
DateInterval
obiekcie:I otrzymujemy poprawny wynik:
Pełny kod użyty do osiągnięcia celu:
źródło
DateTime()
nie jest funkcją, jest obiektem i istnieje od PHP 5.2. Upewnij się, że Twój serwer to obsługuje.Zobacz godziny, minuty i sekundy ..
źródło
Spójrz na poniższy link. To najlepsza odpowiedź, jaką do tej pory znalazłem .. :)
http://www.bizinfosys.com/php/date-difference.html
źródło
Głosowałem za Jurka „s odpowiedź jak to mój ulubiony, ale mam wersję pre-php.5.3 ...
Odkryłem, że pracuję nad podobnym problemem - w ten sposób przede wszystkim dotarłem do tego pytania - ale potrzebowałem tylko różnicy godzin. Ale moja funkcja rozwiązała to całkiem nieźle i nie mam nigdzie w mojej własnej bibliotece, aby przechowywać ją tam, gdzie nie zostanie zgubiona i zapomniana, więc ... mam nadzieję, że jest to przydatne dla kogoś.
I test:
A wynik:
Stąd otrzymałem oryginalny pomysł , który zmodyfikowałem dla moich zastosowań (i mam nadzieję, że moja modyfikacja pojawi się również na tej stronie).
Możesz bardzo łatwo usunąć interwały, których nie chcesz (powiedz „tydzień”), usuwając je z
$aIntervals
tablicy lub dodając$aExclude
parametr, lub po prostu odfiltrowując je, gdy wypisujesz ciąg.źródło
week
indeks w$aIntervals
(ponieważDateDiff
nigdy tego nie używa).źródło
Nie wiem, czy używasz frameworka PHP, czy nie, ale wiele frameworków PHP ma biblioteki daty / godziny i pomocniki, które pomogą Ci powstrzymać się od ponownego wynalezienia koła.
Na przykład CodeIgniter ma
timespan()
funkcję. Po prostu wprowadź dwa znaczniki czasu Unix, a automatycznie wygeneruje taki wynik:http://codeigniter.com/user_guide/helpers/date_helper.html
źródło
Użyj przykładu:
Wynik :
Funkcja:
źródło
Mam do tego prostą logikę:
źródło
Możesz użyć
funkcja, która zwraca tablicę zawierającą wszystkie elementy podanej daty / godziny:
Jeśli data początkowa i końcowa mają format ciągów, użyj
przed powyższym kodem
źródło
$my_t["year"] -= 1970
aby uzyskać prawidłową liczbę lat. Należy również odjąć swój różnicę godziny od GMT, aby uzyskać prawo godzin. Musisz również odjąć 1 od miesiąca i daty.źródło
To moja funkcja. Wymagane PHP> = 5.3.4. Używa klasy DateTime. Bardzo szybko, szybko i może zrobić różnicę między dwiema datami, a nawet tak zwanym „czasem od”.
źródło
Wolałbym używać
date_create
idate_diff
obiektów.Kod:
Wynik:
Aby uzyskać więcej informacji, przeczytaj instrukcję PHP
date_diff
źródło
Spróbuje to wykryć, czy podany został znacznik czasu, a także zwróci przyszłe daty / godziny jako wartości ujemne:
Przykładowe użycie:
Lub:
źródło
„jeśli” data jest przechowywana w MySQL, łatwiej jest mi wykonać obliczenie różnicy na poziomie bazy danych ... Następnie na podstawie danych wyjściowych Dzień, Godzina, Min, Sek, parsowanie i wyświetlanie wyników odpowiednio ...
źródło
Znalazłem twój artykuł na następnej stronie, która zawiera szereg odniesień do obliczeń daty i godziny w PHP .
Oblicz różnicę między dwiema datami (i czasem) za pomocą PHP. Następująca strona zawiera szereg różnych metod (łącznie 7) do wykonywania obliczeń daty / godziny za pomocą PHP, w celu ustalenia różnicy czasu (godziny, munity), dni, miesięcy lub lat między dwiema datami.
Zobacz PHP Data Godzina - 7 metod obliczania różnicy między 2 datami .
źródło
Możesz także użyć następującego kodu, aby zwrócić różnicę daty o ułamki zaokrąglone w górę $ date1 = $ duedate; // przypisanie terminu echo $ date2 = data („Ymd”); // bieżąca data $ ts1 = strtotime ($ date1); $ ts2 = strtotime ($ date2); $ seconds_diff = $ ts1 - $ ts2; echo $ datediff = ceil (($ seconds_diff / 3600) / 24); // powrót za kilka dni
Jeśli użyjesz metody podłogowej php zamiast sufitu, zwróci ci ona okrągłą frakcję w dół. Sprawdź różnicę tutaj, czasami, jeśli strefa czasowa serwerów pomostowych jest inna niż strefa czasowa witryny na żywo, w takim przypadku możesz uzyskać inne wyniki, więc odpowiednio zmień warunki.
źródło
źródło
zawsze możesz skorzystać z następującej funkcji, która może przywrócić wiek w latach i miesiącach (tj. 1 rok 4 miesiące)
lub jeśli chcesz, aby wiek był obliczany na bieżącą datę, możesz użyć
źródło
Dla wersji php> = 5.3: Utwórz dwa obiekty daty, a następnie użyj
date_diff()
funkcji. Zwróci obiekt DateInterval php . patrz dokumentacjaźródło
Oto kod do uruchomienia
źródło
Miałem ten sam problem z PHP 5.2 i rozwiązałem go za pomocą MySQL. Może nie być dokładnie tym, czego szukasz, ale to załatwi sprawę i zwróci liczbę dni:
Więcej informacji tutaj http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_datediff
źródło
Ponieważ wszyscy publikują próbki kodu, oto inna wersja.
Chciałem, aby funkcja wyświetlała różnice od sekund do lat (tylko jedna jednostka). W przypadku okresów dłuższych niż 1 dzień chciałem, aby kumulował się o północy (10 rano w poniedziałek widziany od 9 rano w środę jest 2 dni temu, a nie 1). I dla okresów powyżej miesiąca chciałem, aby rolowanie miało miejsce tego samego dnia miesiąca (w tym dla miesięcy 30 i 31 dni przestępnych).
Oto co wymyśliłem:
źródło
Jakiś czas temu napisałem
format_date
funkcję, ponieważ daje wiele opcji, w jaki sposób chcesz mieć swoją datę :źródło
Bardzo prosta:
Proszę sprawdzić poniższy link, aby uzyskać szczegółowe informacje:
PHP: date_diff - Manual
Zauważ, że dotyczy PHP 5.3.0 lub nowszego.
źródło
Łatwa funkcja
Użyj jak
echo time_difference ($time_1, $time_2, "day");
Wróci jak
2 years 8 months 2 days
źródło
Wypróbuj tę bardzo prostą odpowiedź za pomocą date_diff () , to jest przetestowane.
dane wyjściowe to:
źródło
Korzystam z następującej funkcji, którą napisałem, gdy PHP 5.3 (odpowiednio date_diff ()) nie jest dostępne:
źródło
DateInterval
jest świetne, ale ma kilka zastrzeżeń:Aby temu zaradzić, napisałem następujące (poprawione z odpowiedzi @enobrev ):
Działa dwie pętle; pierwszy dotyczy względnych przedziałów (lat i miesięcy) za pomocą brutalnego wymuszania, a drugi oblicza dodatkowe przedziały bezwzględne za pomocą prostej arytmetyki (więc jest szybszy):
źródło