2014-01-15 5 views
-1
указываете ей

У меня есть функция, которая вычислить разницу дней между двумя датами:PHP ад

function daysBetweenDates($startDate, $endDate) { 
    list($year1, $month1, $day1) = explode('-', $startDate); 
    list($year2, $month2, $day2) = explode('-', $endDate); 
    $f = mktime(0, 0, 0, $month2, $day2, $year2); 
    $i = mktime(0, 0, 0, $month1, $day1, $year1); 
    $difference = $f - $i; 
    $days = floor($difference/86400); 
    return $days; 
} 

Проблема заключается в том, что этот код получает странные результаты с некоторыми датами. Например, если $startDate = '2014-10-14' и $endDate = '2014-10-28', выход этой функции всюду равен 14, но я получаю 13.
Я проверил некоторые онлайн-переводчики php и по какой-то чертовой причине я не знаю, почему, мой mktime возвращает мне разные значения.

Пример:

на 3v4l.org работает mktime(0, 0, 0, 10, 28, 2014) возвращается 1414450800 для PHP versions 5.1.0 - 5.5.8
на 3v4l.org работает mktime(0, 0, 0, 10, 14, 2014) возвращается 1413237600 для PHP versions 5.1.0 - 5.5.8
Выход функции с этими значениями является 14.

В моем коде, когда я запускаю те же значения на mktime, я получаю 1414461600 и 1413255600 соответственно. Выполняя этот код, выход функции 13.

И я бегу на PHP 5.3.3.

Любая помощь при понимании, что не так с моей конфигурацией среды/php/ошибкой функции/неправильным кодом, будет очень признательна.

+2

Есть ли переход на летнее время между датами в настройке часового пояса по умолчанию, определенном в файле php.ini? –

+0

Разница между этими двумя отметками времени составляет 13 дней 23 часа. Таким образом, должно произойти изменение ДСТ. – Barmar

+1

Попробуйте использовать 'round()' вместо 'floor()'. – Barmar

ответ

3

Использование DateTime, а не указываете ей будет конец ад: -

function daysBetweenDates($startDate, $endDate) { 
    $startDate = new \DateTime($startDate); 
    $endDate = new \DateTime($endDate); 
    return $startDate->diff($endDate)->days; 
} 

вы должны получить близко к тому, что вам нужно. Он будет учитывать любые изменения DST под капотом, что, вероятно, является вашей проблемой, так как DST (в Великобритании в любом случае) заканчивается 26 октября этого года.

Например даты, это возвращает 14

присвоенный http://php.net/datetime

+0

В чем причина голосования по этому поводу? – vascowhite

+0

Ну, я думаю, что проблема имеет какое-то отношение к DST. Попробуй ответить. – MurifoX

+0

@MurifoX Да, я объясню это в ответе. – vascowhite

1

Значение mktime основывается на текущем часовом поясе. Значения, которые вы даете mktime, являются «настенными часами», они возвращают абсолютную отметку времени UNIX в истории человека. Для этого он должен учитывать ваш текущий часовой пояс, заданный date_default_timezone_set. Если между этими двумя временами происходит переход на летнее время, между этими двумя часами может наблюдаться более частый момент настенных часов, чем в других часовых поясах. Таким образом, день не гарантируется ровно на 86400 секунд, и вы сталкиваетесь с этой проблемой здесь. Короче: это слишком наивный способ делать вычисления разницы во времени, потому что вы игнорируете все факторы, делающие человеческие времена такими запутанными. См. Ответ @ vascowhite о том, как использовать существующие библиотеки, которые учитывают все это.

0

Возврат функции mktime() основан на текущем часовом поясе.

Если вы хотите вернуть отметку времени для GMT, просто используйте функцию gmmktime().

Или вы можете установить параметр $is_dst в функции mktime() на 0, что означает, что DST игнорируется.