tags:

views:

37

answers:

3

I have two dates - a start date and an end date. I need to return an array of months ('Y-m' format) which includes every month between start and end date, as well as the months that those dates are in. I've tried:

$start = strtotime('2010-08-20');
$end = strtotime('2010-09-15');
$month = $start;
while($month <= $end) {
  $months[] = date('Y-m', $month);
  $month = strtotime("+1 month", $month);
}

The problem is that, in the above example, it only adds '2010-08' to the array, and not '2010-09'. I feel like the solution should be obvious, but I just can't see it.

Note that this should take into account situations like:

$start = strtotime('2010-08-20');
$end = strtotime('2010-08-21');
// should return '2010-08'

$start = strtotime('2010-08-20');
$end = strtotime('2010-09-01');
// should return '2010-08,2010-09'

$start = strtotime('2010-08-20');
$end = strtotime('2010-10-21');
// should return '2010-08,2010-09,2010-10'

Also, the version of PHP on my host is 5.2.6 so it has to work within those confines.


The solution I used was based on the answer below re. setting $start to the first day of the month. However I couldn't get it working with just the strtotime() and instead had to use another function I found on the web.

function firstDayOfMonth($uts=null) 
{ 
    $today = is_null($uts) ? getDate() : getDate($uts); 
    $first_day = getdate(mktime(0,0,0,$today['mon'],1,$today['year'])); 
    return $first_day[0]; 
}

$start = strtotime('2010-08-20');
$end = strtotime('2010-09-15');
$month = firstDayOfMonth($start);
while($month <= $end) {
  $months[] = date('Y-m', $month);
  $month = strtotime("+1 month", $month);
}
A: 

The problem is that $start day is bigger than end day, so after you add month to start its bigger than end, solution is to use first day of the month, like 2010-08-01 so after you add +1 month you will get at least equal $end ;)

cichy
I really wanted to like your solution since it's clean/logical, and when I tested on my Mac using `strtotime('first day of this month', $month)` it worked fine, returning the first day of the month defined in `$month`. But when I did exactly the same thing on my host it returned 1970-01-01 instead.
dosboy
This put me on the right track. Have provided full solution in the question.
dosboy
A: 

This should do what you need.

$start = strtotime('2010-08-20');
$end = strtotime('2010-10-15');
$month = $start;
$months[] = date('Y-m', $start);
while($month <= $end) {
  $month = strtotime("+1 month", $month);
  $months[] = date('Y-m', $month);
}
Centurion
This almost works, but it falls apart when $start and $end are in the same month.
dosboy
It will return start month either way, just if $start and $end are in the same month it wouldn't enter the while, the array month will just contain $start. Try print_r($months); after while and you will see.
Centurion
Tested this locally on PHP 5.3.1 using `$start = strtotime('2010-08-20'); $end = strtotime('2010-08-21');` and in this case it still enters the loop, increments `$month` and writes a second month to the array.
dosboy
A: 

Add a

if( date('d',$month) != date('d',$end) )
   $months[] = date('Y-m', $month);

below the loop. This means, you add the last month if its only partially contained in $end (days are different: last difference is smaller than a month).

rbo

rubber boots
This also fails when $start and $end are in the same month.
dosboy