Рассмотрим этот код, в котором мы хотим, чтобы добавить или вычесть один второй:Есть ли strtotime() ошибка?
date_default_timezone_set("Europe/Amsterdam");
$time = 1477789199;
echo $time . ' - ' . date('r', $time) . "\n";
// 1477789199 - Sun, 30 Oct 2016 02:59:59 +0200
Это правильно, так как это метка времени остается только в DST (летнее время/летнее время).
Но теперь давайте добавим одну секунду метки времени целым числом, а выход DST:
$new = $time + 1;
echo $new . ' - ' . date('r', $new);
// 1477789200 - Sun, 30 Oct 2016 02:00:00 +0100
Ура! PHP видит, что через одну секунду больше нет DST и показывает правильную временную строку.
Но что, если мы не добавим вторую метку времени для целого, но мы использовали strtotime()
добавить, что одна секунда:
$new = strtotime('+1 second', $time);
echo $new . ' - ' . date('r', $new);
// 1477792800 - Sun, 30 Oct 2016 03:00:00 +0100
Yikes! Мы пропустили более одного часа вместо одной секунды. И даже не важно, добавляете ли вы одну секунду, один час, один день или один год, вы всегда получите один дополнительный час. Даже если вы добавите несколько лет, вы получите только один лишний час, что было бы странно, потому что мы каждый год входим и выходим из DST, но вы получаете только один дополнительный час, независимо от того, сколько лет вы добавляете.
Но раз мы exit DST в октябре и вычесть одну секунду, все идет хорошо ...
Но с другой стороны. Если бы мы были в марте, и мы только что вошли в DST, и мы вычитаем одну секунду, мы наблюдаем точно то же самое в обратном порядке.
Подождите, что?! Так ... ?
echo strtotime('+ 1 second - 1 second', 1477789199); // echoes 1477792799
Вау ...
Для меня это звучит как ошибка. Или это «по дизайну»? Кто-нибудь знает, что это где-то документально, или нужно сообщить об этом?
К сожалению. Если бы я проверил пул ошибок PHP перед публикацией, я бы нашел, что аналогичная проблема будет опубликована в 2012 году без последующих действий: https://bugs.php.net/bug.php?id=62185 –
Из [doc] (http://php.net/manual/en/function.strtotime.php): 'Использование этой функции для математических операций нецелесообразно. Лучше использовать DateTime :: add() и DateTime :: sub() в PHP 5.3 и более поздних версиях, или DateTime :: modify() в PHP 5.2. ' –
Сообщается на https://bugs.php.net/bug.php?id=73138 –