Получить последние 12 месяцев в PHP

Итак, вот интересная проблема, которую я узнал сегодня.

Мне нужно заполнить массив за последние 12 месяцев, начиная с прошлого месяца. Так что в августе 2011 года последние 12 месяцев будут с сентября 2010 года по июль 2011 года. Для этого я использую:

for ($i = 1; $i <= 12; $i++) $months[] = date("Ym%", strtotime("-$i months")); 

Код выше работает очень хорошо 30 августа. Я получаю последние 12 месяцев:

 array 0 => string '2011-07%' (length=8) 1 => string '2011-06%' (length=8) 2 => string '2011-05%' (length=8) 3 => string '2011-04%' (length=8) 4 => string '2011-03%' (length=8) 5 => string '2011-02%' (length=8) 6 => string '2011-01%' (length=8) 7 => string '2010-12%' (length=8) 8 => string '2010-11%' (length=8) 9 => string '2010-10%' (length=8) 10 => string '2010-09%' (length=8) 11 => string '2010-08%' (length=8) 

Но когда я запускаю это 31 августа, я получаю:

 array 0 => string '2011-07%' (length=8) 1 => string '2011-07%' (length=8) 2 => string '2011-05%' (length=8) 3 => string '2011-05%' (length=8) 4 => string '2011-03%' (length=8) 5 => string '2011-03%' (length=8) 6 => string '2011-01%' (length=8) 7 => string '2010-12%' (length=8) 8 => string '2010-12%' (length=8) 9 => string '2010-10%' (length=8) 10 => string '2010-10%' (length=8) 11 => string '2010-08%' (length=8) 

Я попробовал как Windows, так и Unix. У кого-нибудь есть решение для этого?

Solutions Collecting From Web of "Получить последние 12 месяцев в PHP"

Я уверен, что у кого-то есть более элегантное решение, но вы можете начать считать назад с 1-го числа этого месяца.

 for ($i = 1; $i <= 12; $i++) { $months[] = date("Ym%", strtotime( date( 'Ym-01' )." -$i months")); } 

Это потому, что не каждый месяц имеет 31-й. Поэтому strtotime() продвигается к следующему месяцу. т.е. 4/31 = 5/1.

Вам было бы лучше использовать mktime() для этого, поскольку это глупее, чем strtotime() .

ОБНОВИТЬ

Чтобы воспользоваться умной функцией, такой как strtotime() и избежать отслеживания года для mktime() , следующее мое предложение:

 $month = time(); for ($i = 1; $i <= 12; $i++) { $month = strtotime('last month', $month); $months[] = date("r", $month); } print_r($months); 

Отрегулируйте логику и оптимизируйте ее по своему усмотрению.

Радости разных месяцев. strtotime в буквальном смысле, и взятие «31 августа» и tryinn сделать «Sep 31», которого не существует. Итак, вы закончили с 1 октября или что-то в этом роде. Более безопасный подход заключается в следующем:

 for ($i = 1; $i <= 12; $i++) { $months[] = date("Ym%", mktime(0, 0, 0, $i, 1, 2011)); } 

strtotime иногда бывает магическим, но он не является надежным и, конечно, не «быстрым».

Проблема в том, что, поскольку PHP обеспокоен, у месяца всегда будет 30 дней, поэтому 31 августа минус 1 месяц – это еще август. Следующий код может быть не самым эффективным или блестящим, но он выполняет следующие действия:

 <?php $m = strftime('%m'); $y = strftime('%Y'); for($i=1; $i<12; $i++) { $m--; if($m <= 0) { $y--; $m = 12; } print "$y-$m\n"; } ?>