Подтвердить что ты не робот

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

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

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

for ($i = 1; $i <= 12; $i++)
    $months[] = date("Y-m%", 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. У кого-нибудь есть решение для этого?

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

UPDATE

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

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

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

Ответ 3

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

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

strtotime иногда бывает магическим, но он не надежный и, конечно, не "быстрый".

Ответ 4

Проблема заключается в том, что, поскольку 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";
}

?>