Есть ли какая-либо функция, эквивалентная DateTime :: diff () в PHP 5.2?
Мой локальный сервер – PHP 5.3 и использует DateTime :: diff (). то я обнаружил, что мой сайт использует PHP 5.2 и дает ошибку.
Fatal error: Call to undefined method DateTime::diff() in /var/www/some/other/dir/web/daikon/modules/projects/views/admin/log/admin_log_list.php on line 40
Код PHP:
foreach ($logs as $key => $list){ ... // show date in European way dd-mm-yyyy not in MySQL way yyyy-mm-dd $newdate =new DateTime($list['date']) ; echo "<td class=\"left\" width=\"8%\">".$newdate->format('dm-Y')."</td>\n"; $starttime = new DateTime($list['start_time']); echo "<td width=\"7%\">".date_format($starttime, 'H:i')."</td>\n"; $finishtime = new DateTime($list['finish_time']); echo "<td width=\"8%\">".date_format($finishtime, 'H:i')."</td>\n"; $timediff = 0; $interval = $starttime->diff($finishtime); $hours = $interval->format('%h'); $minutes = $interval->format('%i'); $timediff = $hours * 60 + $minutes;
Ответ Spudley не работает для меня – вычитание любой DateTime из другого дает 0 в моей системе.
Мне удалось заставить его работать, используя формат DateTime :: с спецификатором «U» (секунды с эпохи Unix):
$start = new DateTime('2010-10-12'); $end = new DateTime(); $days = round(($end->format('U') - $start->format('U')) / (60*60*24));
Это работает как в моей системе dev (5.3.4), так и в моей системе развертывания (5.2.11).
Мне просто нужно было (к сожалению) для плагина WordPress. Это я использую функцию в 2 раза:
В моем вызове класса -> diff () (мой класс расширяет DateTime , поэтому $ this является ссылочной DateTime )
function diff ($secondDate){ $firstDateTimeStamp = $this->format("U"); $secondDateTimeStamp = $secondDate->format("U"); $rv = ($secondDateTimeStamp - $firstDateTimeStamp); $di = new DateInterval($rv); return $di; }
Затем я воссоздал поддельный класс DateInterval (поскольку DateInterval действителен только в PHP> = 5.3) следующим образом:
Class DateInterval { /* Properties */ public $y = 0; public $m = 0; public $d = 0; public $h = 0; public $i = 0; public $s = 0; /* Methods */ public function __construct ( $time_to_convert /** in seconds */) { $FULL_YEAR = 60*60*24*365.25; $FULL_MONTH = 60*60*24*(365.25/12); $FULL_DAY = 60*60*24; $FULL_HOUR = 60*60; $FULL_MINUTE = 60; $FULL_SECOND = 1; // $time_to_convert = 176559; $seconds = 0; $minutes = 0; $hours = 0; $days = 0; $months = 0; $years = 0; while($time_to_convert >= $FULL_YEAR) { $years ++; $time_to_convert = $time_to_convert - $FULL_YEAR; } while($time_to_convert >= $FULL_MONTH) { $months ++; $time_to_convert = $time_to_convert - $FULL_MONTH; } while($time_to_convert >= $FULL_DAY) { $days ++; $time_to_convert = $time_to_convert - $FULL_DAY; } while($time_to_convert >= $FULL_HOUR) { $hours++; $time_to_convert = $time_to_convert - $FULL_HOUR; } while($time_to_convert >= $FULL_MINUTE) { $minutes++; $time_to_convert = $time_to_convert - $FULL_MINUTE; } $seconds = $time_to_convert; // remaining seconds $this->y = $years; $this->m = $months; $this->d = $days; $this->h = $hours; $this->i = $minutes; $this->s = $seconds; } }
Надеюсь, что это помогает кому-то.
Я использую это, похоже, работает нормально – очевидно, вы можете добавить второй параметр, чтобы сделать его более гибким:
function GetDateDiffFromNow($originalDate) { $unixOriginalDate = strtotime($originalDate); $unixNowDate = strtotime('now'); $difference = $unixNowDate - $unixOriginalDate ; $days = (int)($difference / 86400); $hours = (int)($difference / 3600); $minutes = (int)($difference / 60); $seconds = $difference; // now do what you want with this now and return ... }
Я пытался улучшить ответ Кристофера Пикслея.
Я сделал эту функцию, которая возвращает и объект с большинством свойств из исходного объекта DateInterval
.
Не существует свойства «дней», потому что на моем тестовом сервере (например, всегда возвращается 6015) возникает некоторая ошибка .
Кроме того, я предполагаю, что каждый месяц имеет 30 дней, что определенно неточно, но может помочь.
function dateTimeDiff($date1, $date2) { $alt_diff = new stdClass(); $alt_diff->y = floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24*365)); $alt_diff->m = floor((floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365))/30); $alt_diff->d = floor(floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365) - ($alt_diff->m * 30)); $alt_diff->h = floor( floor(abs($date1->format('U') - $date2->format('U')) / (60*60)) - ($alt_diff->y * 365*24) - ($alt_diff->m * 30 * 24 ) - ($alt_diff->d * 24) ); $alt_diff->i = floor( floor(abs($date1->format('U') - $date2->format('U')) / (60)) - ($alt_diff->y * 365*24*60) - ($alt_diff->m * 30 * 24 *60) - ($alt_diff->d * 24 * 60) - ($alt_diff->h * 60) ); $alt_diff->s = floor( floor(abs($date1->format('U') - $date2->format('U'))) - ($alt_diff->y * 365*24*60*60) - ($alt_diff->m * 30 * 24 *60*60) - ($alt_diff->d * 24 * 60*60) - ($alt_diff->h * 60*60) - ($alt_diff->i * 60) ); $alt_diff->invert = (($date1->format('U') - $date2->format('U')) > 0)? 0 : 1 ; return $alt_diff; }
Да, это раздражает, что функция не попала в PHP5.2.
Предположим, вы не можете обновить до 5.3? Вы должны изучить это; есть очень мало причин не обновлять; но я предполагаю, что вы не можете по какой-либо причине.
Первый совет: если вам нужна разница менее 24 часов, вы можете просто вычесть две метки времени и сделать $time_diff = date('H:i:s',$subtracted_value);
Если вы делаете более 24-часовой разницы, но вы в порядке, просто возвращая количество дней вместе с разницей во времени, вы можете расширить описанную выше технику, выполнив вычисление модуля по вычитаемому значению, против количества секунд в день (т.е. 24 * 60 * 60, что составляет 86400)
$subtracted_value = $date1 - $date2; $days_diff = $subtracted_value % 86400; $time_diff = date('H:i:s',$subtracted_value);
Если вам нужны недели, вы можете, конечно, сделать $days_diff % 7
.
К сожалению, ручная техника ломается после нескольких недель, потому что месяцы и годы имеют переменную длину (технически дни тоже, учитывая летнее время, но вы, вероятно, можете игнорировать это, тем более, что вы только когда-нибудь будете на один час, больше всего), но, надеюсь, это достаточно хорошо, чтобы вы начали.
Прочтите вкладки contrib на странице PHP date_diff http://us3.php.net/manual/en/function.date-diff.php
Spudley был близок, но вам нужно использовать gmdate not date.
Таким образом, это работает 24 часа или меньше (если это по крайней мере положительное значение):
$difference = $date2->format('U') - $date1->format('U'); $time_diff = gmdate('H:i:s',$difference);
PHP имеет методы работы с отметками времени Unix.
Как было отмечено другими, работая с секундами с даты Unix, легко рассчитать времена.
PHP strtotime () преобразует дату в метку времени:
$diff = round((strtotime($list['start']) - strtotime($list['finish'])) / 86400);
Если вы хотите рассчитать до текущего времени, time () предоставляет временную метку «now»:
$diff = round((time() - strtotime($list['date'])) / 86400);
86400 – это количество секунд в день.
Если вы хотите конвертировать в годы, используйте 31557000, что почти точно 365.24219 * 86400.
Дополнительным преимуществом здесь является то, что strtotime может принимать дату ввода практически в любом удобочитаемом формате, поэтому очень легко работать с кодом.
Обратите внимание, что если ваш объект DateTime был создан из строки даты без какой-либо информации о часовом поясе (как в '2012-01-01 05:00:00', как из mysql), то установка часового пояса позже с помощью объектов DateTimeZone через setTimeZone () не меняйте временную метку объекта DateTime.
$localtime = new DateTime('2012-01-01 08:00:00+02:00'); // Europe/Copenhagen (+ daylight savings) $localtime->setTimezone(new DateTimeZone('UTC')); // convert local time to utc $utctime = new DateTime('2012-01-01 06:00:00'); // timezone assumed utc, but is in fact unknown $utctime->setTimezone(new DateTimeZone('UTC')); // trying to rectify missing timezone which fails, because the internal timestamp isn't modified, although any other format than 'U' may indicate so #$utctime = new DateTime('2012-01-01 06:00:00+00:00'); // timezone stated, this works $diff = intval($localtime->format('U')) - intval($utctime->format('U')); echo $diff; // expecting zero
Вот лучшее решение для вашего вопроса.
<?php /* Find difference between two dates in days. PHP 5.2.x. */ $d1 = date('Ym-d', strtotime('2013-06-13')); $d2 = date("Ymd"); echo diff($d1, $d2); function diff($date1, $date2) { $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)); return $days; } ?>