Just felt like putzing around with this a bit, so here's what I came up with (including a bunch of defensive coding):
/*
* int nthDay(int $month, str $day, int $n[, int $year])
* returns UNIX timestamp or FALSE on failure
* $day is 'monday', 'tuesday', etc. (case-insensitive)
* $year defaults to current year
*/
function nthDay($month, $day, $n, $year = 0)
{
$month = (int) $month;
$day = strtolower($day);
$year = ($year) ? (int) $year : (int) date('Y');
$n = (int) $n;
if(!checkdate($month, 1, $year))
{
user_error("nthDay(): invalid month and/or year");
return(FALSE);
}
if($n < 1 or $n > 4)
{
user_error("nthDay(): invalid value '$n' for 3rd parameter");
return(FALSE);
}
if(!in_array($day, array('monday', 'tuesday', 'wednesday', 'thursday',
'friday', 'saturday', 'sunday')))
{
user_error("nthDay(): invalid day '$day'");
return(FALSE);
}
return strtotime("+$n weeks", strtotime("Last $day",
mktime(0, 0, 0, $month, 1, $year)));
}
// sample usage:
printf("Thanksgiving this year: %s", date('Y-m-d', nthDay(11, 'Thursday', 4)));