Проблема с функцией PHP strtotime при использовании порядковых значений
Я иногда получаю неожиданные результаты при использовании порядковых значений с strtotime. Например, почему
date("M j", strtotime("second Tuesday February 2011"))
Результат "15 февраля" (который на самом деле является третьим вторником в 2011 году?
3 ответа:
Вы пропускаете "оф".
$ php-r ' echo date ("M j", strtotime ("второй вторник февраля 2011")); '
15 февраля$ php-r ' echo date ("M j", strtotime ("второй вторник февраля 2011 года")); '
8 февраляВерсия PHP:
$ php-v
PHP 5.3.3 (cli) (построен: 22 августа 2010 19: 41: 55)
Copyright (c) 1997-2010 The PHP Group
Зенд двигателя V2.3.0, Авторское право (c) 1998-2010 Зенд технологийДокументация сообщает вам причину этого:
Также заметьте, что" из "в" порядковом пространство dayname пространство 'of' и 'last' пространство dayname " и "" не нечто особенное.
Он устанавливает день месяца равным 1.
- "порядковый номер дня 'of' " не имеет значения переходите на другой день. (Образец: "первый вторник июля 2008 года" означает "2008-07-01").
- "порядковое имя дня" делает переходите на другой день. (Образец: "первый вторник июля 2008 года" означает "2008-07-08", см. Также пункт 4 в список выше).
Руководство для strtotime () рассказывает, что вы ищете
Короче говоря, это ошибка в версии, которую вы используете.В PHP 5 до версии 5.2.7, запрашивая данное наступление данного дня недели в месяц, в котором этот будний день был последним. первый день месяца будет неправильно добавить одну неделю к возвращенная метка времени. Это уже было исправлено в 5.2.7 и более поздних версиях.
Если вы ищете какое-то применимое исправление, отбросьте порядковое значение кажется, работает (как будто первый/второй / третий указывают полные недели)
echo date("M j", strtotime("Tuesday February 2011")), '<br>'; echo date("M j", strtotime("first Tuesday February 2011")), '<br>'; echo date("M j", strtotime("second Tuesday February 2011")), '<br>'; echo date("M j", strtotime("third Tuesday February 2011")), '<br>';
Похоже, что небезопасно полагаться на strtotime для вычисления порядковых дат - по крайней мере, в версиях PHP
Добавление "of", как было предложено, по-видимому, работает только в php 5.3+, и удаление порядкового номера полностью вернет" первое " вхождение, но другие ординалы будут 7 дней.
Кажется, что лучшее решение для PHP 5.2 будьте чем-то вроде этого:
$recurrOrdinal = "last"; $dayOfWeek = "Thursday"; $monthYear = "March 2011"; echo ordinalDate($recurrOrdinal, $dayOfWeek, $monthYear); function ordinalDate($recurrOrdinal, $dayOfWeek, $monthYear) { $firstDate = date("j", strtotime($dayOfWeek . " " . $monthYear) ); if ($recurrOrdinal == "first") $computed = $firstDate; elseif ($recurrOrdinal == "second") $computed = $firstDate + 7; elseif ($recurrOrdinal == "third") $computed = $firstDate + 14; elseif ($recurrOrdinal == "fourth") $computed = $firstDate + 21; elseif ($recurrOrdinal == "last") { if ( ($firstDate + 28) <= date("t", strtotime($monthYear)) ) $computed = $firstDate + 28; else $computed = $firstDate + 21; } return date("Y-m-d", strtotime($computed . " " . $monthYear) ); }