web-dev-qa-db-fra.com

Comment lister tous les mois entre deux dates

J'essaie de lister tous les mois entre deux dates.

Par exemple; la date de début est: 2010-12-02 et la dernière date est: 2012-05-06

Je veux lister quelque chose comme ça:

2010-12
2011-01
2011-02
2011-03
2011-04
.
.
.
2012-04
2012-05

C'est ce que j'ai essayé et ça ne marche pas du tout:

    $year_min = 2010;
    $year_max = 2012;
    $month_min = 12;
    $month_max = 5;
    for($y=$year_min; $y<=$year_max; $y++)
    {
        for($m=$month_min; $m<=$month_max; $m++)
        {
            $period[] = $y.$m;
        }
    }
53
Pooya

PHP 5.3

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

le voir en action

PHP 5.4 ou plus récent

$start    = (new DateTime('2010-12-02'))->modify('first day of this month');
$end      = (new DateTime('2012-05-06'))->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";
}

La partie où nous modifions les dates de début et de fin au premier du mois est importante. Si nous ne le faisions pas et que le jour en cours serait plus élevé que le dernier jour de février (28 ans les années non bissextiles, 29 les années bissextiles), cela ferait un saut en février.

178
John Conde

Vous devez faire la différence entre deux mois de la même année et deux mois d’années différentes.

$year_min = substr($row['contractStart'], 0, 4);
$year_max = substr($row['contractEnd'], 0, 4);
$month_min = substr($row['contractStart'], 5, 2);
$month_min = substr($row['contractEnd'], 5, 2);
$period = array();
try {
  if ($year_min > $year_max)
    throw new Exception();
  else if ($year_min == $year_max)
    if ($month_min > $month_max)
      throw new Exception();
    for ($month = $month_min; $month <= $month_max; $month++) {
      $period[] = $month . '-' . $year;
    }
  else {
    for ($month = $month_min; $month <= 12; $month++) {
      $period[] = $month . '-' . $year_min;
    }
    for ($year = $year_min + 1; $year < $year_max; $year++) {
      for ($month = $month_min; $month <= $month_max; $month++) {
        $period[] = $month . '-' . $year;
      }
    }
    for ($month = 1; $month <= $month_max; $month++) {
      $period[] = $month . '-' . $year_max;
    }
  }
  implode("<br />\r\n", $period);
}
catch (Exception $e) {
  echo 'Start date occurs after end date.'
}

C'est pour la dure. Maintenant, il existe un moyen rapide et facile de donner une réponse que je vous recommande de choisir.

9
SteeveDroz
    function getMonthsInRange($startDate, $endDate) {
$months = array();
while (strtotime($startDate) <= strtotime($endDate)) {
    $months[] = array('year' => date('Y', strtotime($startDate)), 'month' => date('m', strtotime($startDate)), );
    $startDate = date('d M Y', strtotime($startDate.
        '+ 1 month'));
}

return $months;
}
7
sulayman

C'était ma solution puisque DateTime n'est pas disponible dans mon environnement de serveur.

$a = "2007-01-01";
$b = "2008-02-15";

$i = date("Ym", strtotime($a));
while($i <= date("Ym", strtotime($b))){
    echo $i."\n";
    if(substr($i, 4, 2) == "12")
        $i = (date("Y", strtotime($i."01")) + 1)."01";
    else
        $i++;
}

Essayez-le: http://3v4l.org/BZOmb

5
CptAJ