Как рассчитать интервал между двумя временными метками unix в php БЕЗ деления на 86400 (60 * 60 * 24)

У меня есть 2 отметки времени unix, я нахожусь в часовом поясе AsiaPacific / Auckland (GMT + 12, DaylightSavings = GMT + 13)

Я хочу рассчитать интервал количества дней между двумя временными метками, где один находится внутри летнего времени, а другой - нет.

Мои примеры дат:

От 7 Feb 2009 (1233925200) до 21 September 2010 (1284985360) (не включая 21-е) см. Здесь 591 день: http://www.timeanddate.com/date/durationresult.html?d1=7&m1=2&y1=2009&d2=21&m2=9&y2=2010

Давайте посчитаем, вот мои временные метки (оба основаны на времени Окленда 00:00)

1284985360-1233925200 = 51060160
51060160 / 86400 = 590.974

Так что да, мне нужен 591. Я не хочу использовать решение "округлить".

Есть ли какой-либо надежный метод, такой как strtotime, но для расчета интервалов дат, желательно, чтобы не требовалось минимум php 5.3+

РЕДАКТИРОВАТЬ: нужно уточнить, я использую STRTOTIME для получения этих временных меток, я думал, что это UTC

EDIT2: я считаю, что нашел проблему. Хотя моя дата окончания была 21 сентября, я фактически использовал time (), чтобы получить дату окончания, а time () возвращал неправильную метку времени, возможно, она не учитывает GMT + 12, независимо от того, что я переключил time () на strtotime (date ('d M Y')), и он вернул правильную метку времени! эврика 591 день


person samsong    schedule 20.09.2010    source источник
comment
Почему вы не хотите использовать очевидное и простое решение деления?   -  person You    schedule 20.09.2010
comment
@ Вы: потому что это дает неправильный результат?   -  person Michael Borgwardt    schedule 20.09.2010
comment
@ Майкл: Нет, это не так. OP заявляет, что это работает, но он не хочет использовать это решение.   -  person You    schedule 20.09.2010
comment
@You: Округление неправильного результата для получения ожидаемого - это не мое определение произведений.   -  person Michael Borgwardt    schedule 20.09.2010
comment
Что-то не так с этими отметками времени. В моей системе (strtotime('2010-09-21')-strtotime('2009-02-07'))/86400 == 591. Помните, что временная метка Unix должна быть в часовом поясе GMT.   -  person Mchl    schedule 20.09.2010
comment
date('Y-m-d H:i:s',1284985360) == '2010-09-20 12:22:40' и date('Y-m-d H:i:s',1233925200) == '2009-02-06 13:00:00', чтобы было понятно, вам нужно округлить результат.   -  person Mchl    schedule 20.09.2010
comment
@Michael: Используя время UTC, это будет работать. Использование других часовых поясов (например, DST) приведет к предсказуемой ошибке, которую можно исправить округлением в большую сторону. Метод работает, поскольку он возвращает правильный ответ при правильном вводе.   -  person You    schedule 20.09.2010
comment
@Michl, ты был прав, я думаю! После того, как что-то не так с этими временными метками, я проверил свои временные метки, я скопировал, вставил ваше strtotime и сравнил их с датами начала / окончания, которые использовало мое приложение php, и да, действительно, дата окончания была другой.Поэтому я проверил, как я получал дату окончания , И я обнаружил, что когда конечная дата не указана в моей базе данных, я использовал time () для ее создания .. time (), похоже, не дает правильную метку времени в отношении разницы часовых поясов, поэтому я попробовал: strtotime ( date ('d M Y')), и это сработало!   -  person samsong    schedule 21.09.2010


Ответы (3)


Перед вычислением разницы вычислите количество полных дней для обеих временных меток:

floor(1284985360 / 86400) - floor(1233925200 / 86400)

Ваш результат всегда целое число.

И поскольку вы используете strtotime для получения этих отметок времени, укажите время 00:00:00+0000, чтобы всегда получать значения, кратные 86400:

strtotime($str.' 00:00:00+0000')
person Gumbo    schedule 20.09.2010
comment
@ Гамбо Вы, сэр, гений. Это, наконец, способ сделать количество дней между расчетами с использованием временных меток unix, без класса DateTime (для тех из нас, у кого нет PHP5.3). - person Shackrock; 09.03.2013

Правильная метка времени Unix (POSIX) находится в формате UTC, поэтому вы начинаете с уже неправильных значений. Вам предстоит нелегкая битва, поскольку API-интерфейсы обычно предполагают, что метки времени указаны в формате UTC. Лучше всего это исправить, после чего простое деление действительно даст правильный результат.

person Michael Borgwardt    schedule 20.09.2010
comment
Я понятия не имею, есть ли это UTC, я просто запускаю STRTOTIME, поэтому, если вы говорите, что strtotime генерирует GMT вместо UNIX (POSIX), тогда да, думаю, я облажался. Вы кажетесь осведомленным, я полагаю, вы говорите, что нет надежного способа, кроме методов 5.3+ ??? - person samsong; 20.09.2010
comment
@fatjoze: Если быть точным, неправильно сказать, что strtotime генерирует метку времени в определенном часовом поясе. Он всегда генерирует UTC, вопрос в том, какой часовой пояс он использует для интерпретации удобочитаемого параметра даты. И похоже, что в вашем случае это неверно, потому что указанные вами временные метки не соответствуют 00:00 ни по всемирному координированному времени, ни по времени Окленда. Вы можете установить часовой пояс по умолчанию с помощью date_default_timezone_set () - person Michael Borgwardt; 20.09.2010
comment
@fatjoze: На первый взгляд кажется, что ваши временные метки соответствуют 00:00 в Сиднее - возможно ли, что именно там находятся ваши серверы и что они настроены для использования в качестве часового пояса по умолчанию? - person Michael Borgwardt; 20.09.2010
comment
Большое спасибо, Майкл, очень хорошо осведомленная поддержка, мои временные метки ДОЛЖНЫ быть в Окленде, Новая Зеландия, я использовал set_default_date_timezone (забыл фактическое имя), чтобы установить свой часовой пояс соответствующим образом, так что да, не уверен, почему он показывает время в Сиднее. Ты живешь в сиднее? ржу не могу. тем не менее, я последовал решению Гамбоса, разделив оба числа на 86400, затем на пол каждое, ЗАТЕМ вычесть. Пока вроде работает .. - person samsong; 20.09.2010

Делить на 86400 легко и надежно. Никаких специальных функций я не знаю и не вижу смысла в их существовании.

person Māris Kiseļovs    schedule 20.09.2010
comment
В версии 5.3 новый DateTime ($ t1) - ›diff (new DateTime ($ t2)) прост и понятен. Но OP попросил до 5.3 решение. - person Colin Fine; 20.09.2010
comment
Вот почему следует сохранять отметки времени в формате UTC. - person You; 20.09.2010
comment
Чувак, я использую STRTOTIME, чтобы получить эти временные метки, разве не UTC - person samsong; 20.09.2010
comment
STRTOTIME не имеет ничего общего с часовыми поясами. - person Mizipzor; 20.09.2010
comment
@mizipzor: strtotime имеет прямое отношение к часовым поясам - он преобразует удобочитаемую дату в метку времени и должен использовать определенный часовой пояс для интерпретации даты. - person Michael Borgwardt; 20.09.2010