Using the following function I can display the years and months between two dates, but how can I add the correct days for each month as another array within each month? I can't just add the days manually as I need it to account for leap years etc.

function yearMonth($start_date, $end_date)
{
    $begin = new DateTime( $start_date );
    $end = new DateTime( $end_date);
    $interval = new DateInterval('P1M'); // 1 month interval

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

foreach ( $period as $dt )
    $years[$dt->format( "Y" )][] = $dt->format( "F" );

return $years;
}

$list  =  yearMonth("2007-03-24", "2009-06-26");
var_dump($list);  

    From the manual page for [man]date/man, note that the "t" format string gives you the number of days in a month. If you wanted an array of the days, then you could use [man]range/man to create an array from 1 to that number.

      The [font=monospace]t[/font] format gives the number of days in the month containing the date/time; [font=monospace]L[/font] indicates leap years.

        It was an answer more like this I was looking for:

        function yearMonth($start_date, $end_date)
        {
            $begin = new DateTime( $start_date );
            $end = new DateTime( $end_date);
            $interval = new DateInterval('P1D'); // 1 month interval
        
        $period = new DatePeriod($begin, $interval, $end);
        
        $lastMonth = null;
        $lastYear = null;
        $aResult = array();
        foreach ( $period as $dt )
        {
            if ($dt->format('Y') != $lastYear)
            {
                $lastYear = $dt->format('Y');
            }
            if ($dt->format('F') != $lastMonth)
            {
                $lastMonth = $dt->format('F');
            }
            if (!isset($aResult[$lastYear]))
            {
                $aResult[$lastYear] = array();
            }
            if (!isset($aResult[$lastYear][$lastMonth]))
            {
                $aResult[$lastYear][$lastMonth] = array();
            }
            $aResult[$lastYear][$lastMonth][] = $dt->format('d');
        }
        
        return $aResult;
        }  
        
        
        

          In other words, you wanted a less efficient way of going about the answer that you received instead:

          function yearMonth($start_date, $end_date) 
          { 
              $begin = new DateTime( $start_date ); 
              $end = new DateTime( $end_date); 
              $interval = new DateInterval('P1D'); // 1 month interval 
          
          $period = new DatePeriod($begin, $interval, $end); 
          
          $aResult = array(); 
          foreach ( $period as $dt ) 
          {
              $aResult[$dt->format('Y')][$dt->format('F')][] = $dt->format('d');
          } 
          
          return $aResult; 
          } 

          EDIT: Woops, guess it's a bit more than that since you wanted a partial return for the months at the start and end of the range. Okay...

          EDIT2: Was over thinking it... and got fooled by the incorrect "1 month interval" code comment. Corrected code snippet above.

            Thanks that is a more efficient way. I now just need to echo this out into a grid as I am trying to create a Gantt chart layout with years as top row then months then days. Is there a better way of going about that?

              Write a Reply...