3

This questions will seems similar to old ones about month but I have a special issue. I am not trying to count the months between two dates, but I am trying to get the months included in two dates. I explain. I have 2 dates :

$begin = new DateTime( '2014-07-20' );
$end = new DateTime( '2014-10-10' );

Between those two dates, I have 4 months included : July, August, September, October. But with the script I am using, I am not able to find 4 months included but only 3. This is the script :

$interval = DateInterval::createFromDateString('1 month');

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

foreach($period as $dt) {
    echo $dt->format( 'm' );
    $counter++;
}

echo $counter;

How to count all those 4 months in a loop ?

pollux1er
  • 5,372
  • 5
  • 37
  • 36
  • I wish to make a loop throught all those months – pollux1er Sep 10 '14 at 09:04
  • Your example will work only for cases where day in $begin will be smaller than day in $end. Easy solution would be to set day in $begin to 1st day in month, and set day in $end to any day not 1st (2nd, 3rd, or last). [Example of your modified code.](https://eval.in/191289) – Glavić Sep 10 '14 at 12:58

4 Answers4

6

You can do this with simple while() loop:

$begin = new DateTime('2014-07-20');
$end = new DateTime('2014-10-10');

while ($begin <= $end) {
    echo $begin->format('Y-m'), "\n";
    $begin->modify('first day of next month');
}

demo

Glavić
  • 42,781
  • 13
  • 77
  • 107
  • Thanks Glavic, this is very elegant... And it works very well! – pollux1er Sep 11 '14 at 03:27
  • If $begin>$end, it shows nothing. So if you want the list regardless a day of a month, you need some corrections: `$begin = (new DateTime('2014-07-20'))->modify('first day of this month'); $end = new DateTime('2014-07-01');` It will show "2014-07" for such a case; – Sergey Beloglazov Jun 28 '22 at 15:10
1
<?php
$begin = new DateTime( '2014-07-20', new DateTimeZone('Europe/Paris') );
$end = new DateTime( '2014-10-10', new DateTimeZone('Europe/Paris') );
$end->add(new DateInterval("P1M"));
$interval = DateInterval::createFromDateString('1 month');

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

foreach($period as $dt) {
    echo $dt->format( 'm' );
    echo "\n";
    $counter++;
}

echo $counter;

It seems to be a bit tricky, but it should work with any date (i haven't tested a lot tho). I just added a month to the $end date so that it takes account of the fact you want to get all the included months in a certain date interval.

GeoffreyB
  • 1,791
  • 4
  • 20
  • 36
  • Ok, but if you make a loop with the foreach, you will notice the problem is still the same @Lgt – pollux1er Sep 10 '14 at 09:06
  • The problem with the interval here is that it seems to be counting 30 days equivalent to months, it is not telling me which months are in the interval. – pollux1er Sep 10 '14 at 09:10
  • Is it better now ? I haven't tested it a lot, but it works. – GeoffreyB Sep 10 '14 at 09:16
  • It seems not to be working for 2014-07-01 to 2014-09-30 ... Can you test ? It says 4 months but it is only 3 – pollux1er Sep 10 '14 at 10:27
  • It seems the only way to really loop between months is to loop through days of the interval and get months. – pollux1er Sep 10 '14 at 11:01
  • @pollux1er: this example won't even work for dates which begin on day that next month doesn't have. Example: 2014-08-31 + 1month is 2014-10-01 (month 09 is skipped from the loop). My example/answer will work in any-case-scenario. – Glavić Sep 10 '14 at 12:38
0
$begin = strtotime('2014-07-00');
$end= strtotime('2014-10-00');
$y1 = date('Y', $begin);
$y2 = date('Y', $end);
$m1 = date('m', $begin);
$m2 = date('m', $end);
$diff = (($y2 - $y1) * 12) + ($m2 - $m1);
vascowhite
  • 18,120
  • 9
  • 61
  • 77
Akshaya Moorthy
  • 309
  • 3
  • 11
0

For me this is not an optimal solution but it is working well :

$begin = new DateTime( '2014-07-20' );
$end = new DateTime( '2014-10-10' );
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);

$months = array();
foreach($period as $dt) {
    if(!in_array($dt->format( "m" ), $months)) {
        $months[] = $dt->format( "m" );
        echo  $dt->format( "m" );
        echo '<br>';
    }
}
pollux1er
  • 5,372
  • 5
  • 37
  • 36