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>"; ?>