PHP: Get date for nth occurrence of weekday

PHP: Get date for nth occurrence of weekday

I looked quickly and did not see any code out there to determine the nth occurrence of a specific day of the week in a month.  For example Thanksgiving is the 4th Thursday in November.  So I designed the following

<?php
$year = 2012; 
//Pick your year
$interval = 4; 
//Week number, in this case the 4th week
$dayofweek = 4; 
//Day of week 0=Sun, 1=Mon. . .
$month = 11; 
//Month 1=Jan, 2=Feb

$firstday = jddayofweek(gregoriantojd($month, 1, $year), 0);
if($firstday <= $dayofweek){
  $date = (($interval * 7)-6) + ($dayofweek - $firstday);
}else{
  $date = (($interval * 7)-1) + (6 - $firstday);
}
echo date("n/j/Y", mktime(0, 0, 0, $month, $date, $year));
?>

It looks a little messy, but it works perfectly.

 

UPDATE:

So apparently as bad as this looks it works too:

echo date("n/j/Y", strtotime("3 weeks thursday",mktime(0,0,0,11,1,$year)));

But I can’t get it to work correctly for the 1st Thursday in November.  Also I have seen a few comments that strtotime is significantly slower than other functions.

Another user on php.net posted the following, it is a significantly cleaner version of my code:

<?php

function get_day( $describer, $weekday, $reference_date ) {
   //$reference_date format = m-Y    $d = explode('-',$reference_date);
   switch ($describer) {
        case 'first':  
$offset = get_day_offset($reference_date, $weekday); 
break;
        case 'second': 
$offset = get_day_offset($reference_date, $weekday) + 7; 
break;
        case 'third':  
$offset = get_day_offset($reference_date, $weekday) + 14;
break;
        case 'fourth': 
$offset = get_day_offset($reference_date, $weekday) + 21; 
break;
        case 'last':
$reference_date = ($d[0]+1).'-'.($d[1]); 
$d = explode('-',$reference_date);
$offset = get_day_offset($reference_date, $weekday) - 7;
break;
    }
    $r = mktime( 0, 0, 0, $d[0], 1+$offset, $d[1] );
    return $r;  //returns timestamp format}

function get_day_offset( $anchor , $target ) {  
//$anchor format = m-Y
    $ts = explode('-',$anchor);
    $ts = mktime(0,0,0,$ts[0],'01',$ts[1]);
    $anchor = date("w",$ts);
    $target = strtolower($target);
    $days = array( 'sunday'=>0, 'monday'=>1, 'tuesday'=>2, 'wednesday'=>3, 'thursday'=>4, 'friday'=>5, 'saturday'=>6 );
    $offset = $days[$target] - $anchor;
    if ($offset<0) $offset+=7;
    return $offset;  //returns 0-6 for use in get_day()
;}
       $date1 = get_day("second", "saturday", "12-2007");$date2 = get_day("last", "friday", "11-2007");
echo "Second Saturday of December, 2007: ".date("m-d-Y", $date1)."<br>";
echo "Last Friday of November, 2007: ".date("m-d-Y", $date2)."<br>";
?>
Comments are closed.