PHP: цикл по всем месяцам в диапазоне дат? - PullRequest
33 голосов
/ 28 января 2010

Если у меня есть дата начала (скажем, 2009-02-01) и дата окончания (скажем, 2010-01-01), как я могу создать цикл для просмотра всех дат (месяцев) в диапазоне?

Ответы [ 7 ]

75 голосов
/ 28 января 2010

Попробуйте

$start = $month = strtotime('2009-02-01');
$end = strtotime('2011-01-01');
while($month < $end)
{
     echo date('F Y', $month), PHP_EOL;
     $month = strtotime("+1 month", $month);
}

Запомни ноту http://php.net/manual/de/datetime.formats.relative.php

Относительные месячные значения рассчитываются на основе продолжительности месяцев, через которые они проходят. Примером может быть «+2 месяц 2011-11-30», что приведет к «2012-01-30». Это связано с тем, что ноябрь длится 30 дней, а декабрь - 31 день, что составляет в общей сложности 61 день.

Начиная с PHP5.3 вы можете использовать http://www.php.net/manual/en/class.dateperiod.php

34 голосов
/ 28 августа 2013

Пример DateTime , DateInterval и DatePeriod комбинация классов:

$start = new DateTime('2009-02-01');
$interval = new DateInterval('P1M');
$end = new DateTime('2011-01-01');
$period = new DatePeriod($start, $interval, $end);

foreach ($period as $dt) {
    echo $dt->format('F Y') . PHP_EOL;
}
19 голосов
/ 01 октября 2014

Принятый ответ не является правильным.

Я попробовал этот фрагмент, и он не работает должным образом. Если дата начала - это конец месяца, а дата окончания - начало 3-го месяца.

Например: 2014-08-31 - 2014-10-01

Ожидаемое должно быть.

  • Август
  • сентябрь
  • Октябрь

Лучшее решение:

$start    = new DateTime('2010-12-02');
$start->modify('first day of this month');
$end      = new DateTime('2012-05-06');
$end->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period   = new DatePeriod($start, $interval, $end);

foreach ($period as $dt) {
    echo $dt->format("Y-m") . "<br>\n";
}

Ссылка: Как перечислить все месяцы между двумя датами

2 голосов
/ 17 апреля 2015

Мне нравится простота принятого ответа, но как 3s2ng, он не всегда работает. Поэтому я настроил это так:

    $start = strtotime('2009-02-01');
    $startmoyr = date('Y', $start) . date('m', $start);
    $end = strtotime('2013-12-01');
    $endmoyr = date('Y', $end) . date('m', $end);

    while ($startmoyr <= $endmoyr) {
        echo date("F Y", $start) . "<br>";
        $start = strtotime("+1month", $start);
        $startmoyr = date('Y', $start) . date('m', $start);
    }
2 голосов
/ 26 сентября 2013
$start = strtotime('2011-09-01');
$end = strtotime('2013-12-01');
while($start < $end)
{
    echo date('F Y', $start) . '<br>';
    $start = strtotime("+1 month", $start);
}
1 голос
/ 05 сентября 2014

У меня есть метод, который оптимален в результатах:

$begin = new DateTime( '2014-07-14' );
$end = new DateTime( '2014-08-01' );
$end = $end->modify( '+1 month' );
$interval = DateInterval::createFromDateString('1 month');

$period = new DatePeriod($begin, $interval, $end);

foreach($period as $dt) {
    var_dump($dt->format( "m" ));
}

Плюс за метод @ Glavic

0 голосов
/ 05 апреля 2019

Основываясь на ответе Гордона, именно так я и работаю , когда вам нужно получить все месяцы между .

$end = strtotime(date("Y-m-01"));
$start = $month = strtotime("-12 months", $end);

while ( $month < $end ) {
    echo date("Y-m-d", $month));
    $month = strtotime("+1 month", $month);
}

Это результат, если я выполню этот код сейчас:

* +1007 *

Обратите внимание, что это не включает текущий месяц. Если вам нужно включить текущий месяц, вы можете установить переменную «$ end» на первый день следующего месяца.

$current_first_day_of_the_month = date("Y-m-01");
$end = strtotime("$current_first_day_of_the_month +1 month");
$start = $month = strtotime("-12 months", $end);

Надеюсь, это поможет, привет.

...