PHP Strtotime -1month -2month
Это работало нормально вчера, без изменений кода.
echo date("M", strtotime("-3 month", time()) );
echo date("M", strtotime("-2 month", time()) );
echo date("M", strtotime("-1 month", time()) );
echo date("M", time());
Выход, который он производил вчера, был таким, каким вы ожидали бы - а.е., май, июнь, июль
Сегодня он повторяет май май июль июль
Любые идеи?
Спасибо заранее.
Ответы
Ответ 1
Это может быть связано с ошибкой # 44073
Вы можете попробовать что-то вроде этого:
echo date("M", strtotime("-3 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", strtotime("-2 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", strtotime("-1 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", time()) . "\n";
(Решение найдено в разделе комментариев strtotime
; direct ссылка)
И вывод:
Apr
May
Jun
Jul
Вид "обмана" с форматом даты и именем месяца и всем этим...
Ответ 2
Горден правильно определил проблему, но я хотел дать другое решение, которое было бы полезным, а не техническим. Просто используйте "первый день" или "последний день" в своем strtotime. Например, следующие примеры преодолевают проблему 31-го числа месяца:
// Today is May 31st
//All the following return 2012-04-30
echo date('Y-m-d', strtotime("last day of -1 month"));
echo date('Y-m-d', strtotime("last day of last month"));
echo date_create("last day of -1 month")->format('Y-m-d');
// All the following return 2012-04-01
echo date('Y-m-d', strtotime("first day of -1 month"));
echo date('Y-m-d', strtotime("first day of last month"));
echo date_create("first day of -1 month")->format('Y-m-d');
Ответ 3
Попробуйте это вместо strtotime
:
mktime(0, (date("n") - 3 + 12) % 12, 1)
Идея состоит в том, чтобы взять текущий номер месяца (date("n")
), вычесть количество месяцев от него, которое вы хотите (здесь -3
), добавить 12 к нему, а затем получить по модулю 12.
Ответ 4
Это известное и ожидаемое поведение. Причина этого в том, что месяц является относительной датой без фиксированной длины. Из http://www.gnu.org/software/tar/manual/html_node/Relative-items-in-date-strings.html#SEC120
Единица смещения времени может быть выбрана по строке "год" или "месяц" для перемещения целыми годами или месяцами. Это нечеткие единицы, поскольку годы и месяцы не одинаковы. Более точные единицы - "две недели, которые стоят 14 дней", неделя стоит 7 дней, "день стоит 24 часа", "час стоит 60 минут", "минута" или "мин", 60 секунд, и "секунда" или "секунда в одну секунду". Суффикс на этих устройствах принимается и игнорируется.
Следовательно (внимание мое)
Fuzz в единицах может вызвать проблемы с относительными элементами. Например, "2003-07-31 -1 месяц может быть оценен до 2003-07-01, поскольку 2003-06-31 является недопустимой датой. Чтобы более надежно определить предыдущий месяц, вы можете запросить месяц до 15 числа текущего месяца. Например:
$ date -R
Thu, 31 Jul 2003 13:02:39 -0700
$ date --date='-1 month' +'Last month was %B?'
Last month was July?
$ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!'
Last month was June!
Вышеуказанное может быть выражено в PHP как
echo date('M', strtotime(date('Y-m-') . '15 -1 month'));
Также см. пункты ниже http://bugs.php.net/bug.php?id=22486
Ответ 5
Из PHP 5.3 (Ссылка: https://bugs.php.net/bug.php?id=44073) и выше вы можете сделать:
"first day of +1 month
" или "first day of next month
" или даже "last day of next month
"
Пример:
$date = '2015-12-31';
echo date("Y-m-d", strtotime($date ."first day of previous month"));
Будет производить: 2015-11-01
Это не вычисляет дни на основе времени +30 дней.
Ответ 6
простым способом может быть запись этого типа
эхо-дата ( "M", strtotime ( "в этом году +3 месяца" ));
или
эхо-дата ( "M", strtotime ( "в этом месяце -3 месяца" ));
зависит от того, как вы его используете.