PX : code

Nth Weekday of Month by David Cloutman
Download this code


<?php
/*
    (c) 2001 David Cloutman. (www.nokhawaga.com) This script may be freely distributed and modified to 
    individual needs. Please do not redistribute without giving credit.

    This script has only been briefly tested. It may contain undocumented code features. Use at your own
    risk. You may report problems to dwcsite@yahoo.com.

    The author offers no technical support for this script. No warranty is given or implied. Use at your
    own risk.

-----------------------------------------------------------------------------------------------------------

    nthDayOfMonth.inc.php v0.9
    
    Returns the date of next nth weekday of a month. For instance, the next 3rd Tuesday would be called as:
    
        nthDayOfMonth(3, 2);
    
    if you chose to use the default output strings. Other outputs can be specified by using the optional
    arguments.
    
    This string will only return dates within the current and next month. It is possible to specify dates
    such as the next fifth Monday that may not return a date within this period. If there is no valid date,
    the script will return the value of $noDateStr. You can modify the script if this does not suit your needs.
    
    $nthDay - and integer between 1 and 5 that specifies the week of the monthly event.
    $dayNum - 0 == Sunday ... 6 == Saturday
    $dateFormatStr - A string that controls the format of the scripts output. Uses same codes as date(). 
                     See PHP docs.
    $noDateStr - Only returned under special circumstances. What the script returns when a date requested
                 does not occur within the current or next month.
*/
function nthDayOfMonth ($nthDay$dayNum$dateFormatStr "l, F j, Y\", $meetsTodayStr = \"Meets Today!\", $noDateStr = \"To Be Announced\") {
    
    // Debugging feature: Prevents erroneous function calls.
    if ($nthDay > 5 || $nthDay < 1) { return \"Not a valid date.\"; }
    if ($dayNum < 0 || $dayNum > 6) { return \"Not a valid day.\"; }

    $thisMonth = date(\"n\"); // [m]m
    $thisYear = date(\"Y\"); // YYYY
    
    // This Month
    $lastDate = testMonth ($thisMonth, $thisYear, $nthDay, $dayNum);
    
    if (date(\"n/j/Y\") == date(\"n/j/Y\", $lastDate)) { return $meetsTodayStr; } // Returns Meets Today message event is today.
    
    // Next Month
    if (! $lastDate || $lastDate < time()) {
        if ($thisMonth != 12) {
            $thisMonth++;
        }
        else {
            $thisMonth = 1;
            $thisYear++;
        }
        
        $lastDate = testMonth ($thisMonth, $thisYear, $nthDay, $dayNum);
        
    }

    if (! $lastDate) { return $noDateStr; } // If the day specified in the function call does not occur within the two months tested.
    else { return date($dateFormatStr, $lastDate); } // Otherwise, return the date of the next event.
}

// Modularizes the code. This function looks for a future date in the month specified. You can alter the functionality of this algorithm by manipulating the way this function is called in the main part of this script.
function testMonth ($thisMonth, $thisYear, $nthDay, $dayNum) {
    
    $daysOfWeekFound = 0;
    $dayOfMonth = 1;
    
    $daysInMonth = daysInMonth($thisMonth, $thisYear);
    
    while ($daysOfWeekFound < $nthDay && $dayOfMonth <= $daysInMonth) {
        
        $testDateStr = \"$thisMonth/$dayOfMonth/$thisYear\"; // String dd/mm/yyyy must be converted to timestamp.
        
        
        //Last date is a timestamp integer that contains the last date tested.
        $lastDate = strtotime($testDateStr);
        $lastDateArr = getdate($lastDate);
        
        if ($lastDateArr[wday] == $dayNum) { $daysOfWeekFound++; }
        
        $dayOfMonth++;
    
    }
    
    if ($daysOfWeekFound != $nthDay) { return false; }
    return $lastDate;
}

// How many days are in a given month.
function daysInMonth($month, $year) {
    $feb = daysInFeb($year);
    $daysInMonthsArr = array(31, $feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    $monthIndex = $month -1;
    return $daysInMonthsArr[$monthIndex];
}

// Deals with the leap year issue.
// Not Y2.2k compliant.
function daysInFeb($year) {
    if (is_int($year / 4) && ($year != 1900 && $year != 2100) ) { return 29; }
    else { return 28; }
}


?>

Comments or questions?
PX is running PHP 5.2.17
Thanks to Miranda Productions for hosting and bandwidth.
Use of any code from PX is at your own risk.