3

Trying to figure out a small problem. I have a start date and a duration (in weeks) and need to calculate the number of work days per month over the duration.

For example: Start Date: 2011-02-07 Duration: 10 weeks

I'd like to get back the following:

Feb: 16 days March: 23 days April: 11 days

Any help would be great. Thanks.

Brian Hayes
  • 47
  • 1
  • 5
  • Work days from Monday to Friday? – ajreal Jan 12 '11 at 15:27
  • Maybe this could help you figuring it out: [http://stackoverflow.com/questions/4261179/working-days-mon-fri-in-php](http://stackoverflow.com/questions/4261179/working-days-mon-fri-in-php) – yvoyer Jan 12 '11 at 15:35

2 Answers2

4

Pre 5.3 solution:

$start = $current = strtotime('2011-02-07');
$end = strtotime('+10 weeks', $start);
$months = array();
while($current < $end) {
    $month = date('M', $current);
    if (!isset($months[$month])) {
        $months[$month] = 0;
    }
    $months[$month]++;
    $current = strtotime('+1 weekday', $current);
}
print_r($months);

Output (codepad):

Array
(
    [Feb] => 16
    [Mar] => 23
    [Apr] => 11
)
Gordon
  • 312,688
  • 75
  • 539
  • 559
  • @gordon what if the date and the duration are variables? Duration is an int like 10 and date is the same. Sorry should have been more clear. – Brian Hayes Jan 12 '11 at 16:27
  • @Brian not an issue: `strtotime($date); strtotime("+$w weeks")` – Gordon Jan 12 '11 at 16:29
  • @gordon what is I want to add a value to the finial number of days per month? I'm not sure where to add that in as it's counting. – Brian Hayes Jan 12 '11 at 16:57
  • @Brian the approach above does not know when it shifts from one month to the other, so you would have to add a $previousMonth variable and compare that against the $month variable and when they are not the same you know that a new month started. As an alternative simply use `array_walk` or `array_map` on the result array. – Gordon Jan 12 '11 at 17:01
3
$start=date_create('2011-02-07');
$interval=new DateInterval('P10W');
$end=date_add(clone $start,$interval);//use clone otherwise $start gets changed

$period=new DatePeriod($start, new DateInterval('P1D'), $end);

foreach($period as $day){
  if($day->format('N')<6) $workdays[$day->format('F')]++; //N is 1-7 where Monday=1
}

var_dump($workdays);
dnagirl
  • 20,196
  • 13
  • 80
  • 123
  • That's what I get as well. Also how would I set up a variable for DateInterval? – Brian Hayes Jan 12 '11 at 15:51
  • Also I don't think that I have DateInterval available as it's only in 5.3 any way to accomplish this without that? – Brian Hayes Jan 12 '11 at 15:57
  • You need PHP greater or equal to version 5.3.0 – John Giotta Jan 12 '11 at 15:58
  • @Gordon: fixed the syntax error- forgot to close a parenthesis. Also, added `clone` to the `date_add` line because of the weird way that function works. However, you do have to use PHP5.3 or better for this method. For prior versions you can do the math with `date()` but you will likely run into issues with leap years and other edge cases that the new DateTime/DateInterval/DatePeriod objects handle for you. – dnagirl Jan 12 '11 at 16:03
  • @Gordon: the notices are about undefined indices and variable. If you want to avoid them, you can initialize `$workdays=array('January'=>0,...)` before the loop. – dnagirl Jan 12 '11 at 17:12
  • @Gordon: no worries. Were this production code, it would be complete. – dnagirl Jan 12 '11 at 17:20