0

How do I calculate how many days in each month are contained in a time period designated from a start time and and ending time? For example for the time period 4/4/13 to 10/6/13, how many days of each month are included?

  • Check out [How to calculate the difference between two dates using PHP?](http://stackoverflow.com/questions/676824/how-to-calculate-the-difference-between-two-dates-using-php) – Marty McVry Oct 05 '13 at 20:17
  • The term you're looking for is "date arithmetic." http://stackoverflow.com/questions/8235896/date-arithmetic-in-php – Andy Lester Oct 05 '13 at 20:17

1 Answers1

1

Those other answers didn't seem to answer the best way to break it down further than how many total days or months between two dates. I gave it a stab and came up with this to find the number of days for each month between two dates.

I figured the steps would be something like:

  1. Figure out the remaining days in the start month (In this example april has 30 days so starting on 4/4 means 26 days)
  2. Figure out number of months between the beginning of the next month and the last month (in this example 5/1-10/1 (5 months))
  3. Loop and figure out the number of days in the full months between
  4. Add in the total number of days in the last month (6 days)
  5. A side requirement I figured may not be something you need but would be good to have is a way to do this over multiple years.

    $daysInMonths = array(); $start = DateTime::createFromFormat('n/j/y', '4/4/13'); $end = DateTime::createFromFormat('n/j/y', '10/6/14');

    // find days til start of next month
    $daysInMonths[$start->format('Y')][$start->format('n')] = $start->format('t')-$start->format('j');
    
    // calculate months between start of next month and beginning of last month
    $start->modify('first day of next month');
    $end->modify('first day');
    
    // returns DateInterval object
    $dateDiff = $start->diff($end);
    
    //  By multiplying the years by 12 we make sure to account for year spans
    if ($dateDiff->y > 0) {
      $months = $dateDiff->m+(12*$dateDiff->y);
    } else {
      $months = $dateDiff->m;
    }
    
    // find days in those middle months
    // $start has been advanced to the next month, so we need to log the days in that month
    $daysInMonths[$start->format('Y')][$start->format('n')] = $start->format('t')-$start->format('j');
    $numMonths = $months;
    for ($i = 0;$i<$numMonths;$i++) {
      $start->modify('+1 month');
      $daysInMonths[$start->format('Y')][$start->format('n')] = $start->format('t');
    }
    
    
    // log the days in the last month
    $daysInMonths[$end->format('Y')][$end->format('n')] = $end->format('j');
    
    print_r($daysInMonths);
    
    // Array ( [2013] => Array ( [4] => 26 [5] => 30 [6] => 30 [7] => 31 [8] => 31 [9] => 30 [10] => 7 ) )
    
    // if you instead did 4/4/13 - 10/6/14 you would get:
    // Array ( [2013] => Array ( [4] => 26 [5] => 30 [6] => 30 [7] => 31 [8] => 31 [9] => 30 [10] => 31 [11] => 30 [12] => 31 ) [2014] => Array ( [1] => 31 [2] => 28 [3] => 31 [4] => 30 [5] => 31 [6] => 30 [7] => 31 [8] => 31 [9] => 30 [10] => 7 ) )
    
Levi
  • 12,214
  • 14
  • 43
  • 47