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