web-dev-qa-db-fra.com

PHP: boucle à travers tous les mois dans une plage de dates?

Si j'ai une date de début (dites 2009-02-01) et une date de fin (disons 2010-01-01), comment créer une boucle pour parcourir toutes les dates (mois) de la plage?

33
JD Isaacks

Essayer

$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);
}

Attention à la note http://php.net/manual/de/datetime.formats.relative.php

Les valeurs relatives des mois sont calculées en fonction de la durée des mois qu'ils traversent. Un exemple serait "+2 mois 2011-11-30", qui produirait "2012-01-30". Cela est dû au fait que novembre dure 30 jours et décembre 31 jours, ce qui donne un total de 61 jours.

Depuis PHP5.3, vous pouvez utiliser http://www.php.net/manual/en/class.dateperiod.php

77
Gordon

Exemple de combinaison de classes DateTime , DateInterval et 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;
}
34
Glavić

La réponse acceptée n'est pas la bonne façon.

J'ai essayé cet extrait de code et il ne fonctionne pas correctement. Si votre date de début est la fin du mois et la date de fin est le début du 3ème mois.

Par exemple: 2014-08-31 - 2014-10-01

Attendu devrait être.

  • Août
  • Septembre
  • Octobre

La meilleure solution est:

$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";
}

Référence: Comment lister tous les mois entre deux dates

19
3s2ng
$start = strtotime('2011-09-01');
$end = strtotime('2013-12-01');
while($start < $end)
{
    echo date('F Y', $start) . '<br>';
    $start = strtotime("+1 month", $start);
}
2
user2643679

J'aime la simplicité de la réponse acceptée, mais en 3s2ng, cela ne fonctionne pas toujours. Alors je l'ai tweeté comme ceci:

    $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
Mark

J'ai une méthode qui est optimale dans les résultats:

$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" ));
}

Un plus pour la méthode de @Glavic

1
pollux1er

Sur la base de la réponse de Gordon, c'est ainsi que je travaille réellement lorsque vous devez obtenir tous les mois entre les deux.

$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);
}

C'est le résultat si j'exécute ce code maintenant:

2018-05-01
2018-06-01
2018-07-01
2018-08-01
2018-09-01
2018-10-01
2018-11-01
2018-12-01
2019-01-01
2019-02-01
2019-03-01
2019-04-01

Notez que cela n'inclut pas le mois en cours. Si vous devez inclure le mois en cours, vous pouvez définir la variable "$ end" sur le premier jour du mois suivant.

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

J'espère que cela vous aide, salutations.

0
manuman94