PHP Strtotime -1 месяц -2 месяца - PullRequest
12 голосов
/ 31 июля 2009

Вчера все работало нормально, без изменений в коде.

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());

Выход, который он производил вчера, был таким, как вы ожидаете, т.е.

Сегодня это повторяет май май июль июль

Есть идеи?

Заранее спасибо.

Ответы [ 6 ]

13 голосов
/ 31 июля 2009

Это может быть связано с ошибкой # 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; прямая ссылка )

И вывод:

Apr
May
Jun
Jul

Вид «читерства»с форматом даты и названием месяца и всем этим ...

8 голосов
/ 31 мая 2012

Горден правильно определил проблему, но я хотел дать другое решение, которое было бы полезным, а не техническим. Просто используйте «первый день» или «последний день» в вашем 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');
4 голосов
/ 31 июля 2009

Попробуйте вместо strtotime:

mktime(0, (date("n") - 3 + 12) % 12, 1)

Идея состоит в том, чтобы взять номер текущего месяца (date("n")), вычесть из него желаемое количество месяцев (здесь -3), добавить 12 к нему и получить по модулю 12.

3 голосов
/ 31 мая 2011

Это известное и ожидаемое поведение. Причина этого в том, что month является относительной датой без фиксированной длины. От http://www.gnu.org/software/tar/manual/html_node/Relative-items-in-date-strings.html#SEC120

Единица измерения времени может быть выбрана строкой «год» или «месяц» для перемещения на целые годы или месяцы. Это нечеткие единицы, поскольку годы и месяцы не имеют одинаковую продолжительность. Более точными единицами являются «две недели», которые стоят 14 дней, «неделя», равная 7 дням, «день», равный 24 часам, «час», равный 60 минутам, «минута» или «минута», равная 60 секундам, и «секунда» или «сек» стоит одну секунду. Суффикс "s" на этих единицах принимается и игнорируется.

Следовательно (выделено мое)

Нечеткость в единицах может вызвать проблемы с относительными элементами. Например, значение «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

2 голосов
/ 05 марта 2016

Начиная с PHP 5.3 (Ref: 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 дней.

0 голосов
/ 18 марта 2012

простой способ написать так:

дата эха («M», strtotime («в этом году +3 месяца»));

или

дата эха ("M", strtotime ("этот месяц -3 месяца"));

зависит от того, для чего вы его используете.

...