AbleDesign - Programs

Programs > Holiday Calculations

See it in Action

<?php

/* US Holiday Calculations in PHP
 * Version 1.02
 * by Dan Kaplan <design@abledesign.com>
 * Last Modified: April 15, 2001
 * ------------------------------------------------------------------------
 * The holiday calculations on this page were assembled for
 * use in MyCalendar:  http://abledesign.com/programs/MyCalendar/
 * 
 * USE THIS LIBRARY AT YOUR OWN RISK; no warranties are expressed or
 * implied. You may modify the file however you see fit, so long as
 * you retain this header information and any credits to other sources
 * throughout the file.  If you make any modifications or improvements,
 * please send them via email to Dan Kaplan <design@abledesign.com>.
 * ------------------------------------------------------------------------
*/

// Gregorian Calendar = 1583 or later
if (!$_GET["y"|| ($_GET["y"1583) || ($_GET["y"4099)) {
    
$_GET["y"date("Y",time());    // use the current year if nothing is specified
}

function 
format_date($year$month$day) {
    
// pad single digit months/days with a leading zero for consistency (aesthetics)
    // and format the date as desired: YYYY-MM-DD by default

    
if (strlen($month) == 1) {
        
$month "0"$month;
    }
    if (
strlen($day) == 1) {
        
$day "0"$day;
    }
    
$date $year ."-"$month ."-"$day;
    return 
$date;
}

// the following function get_holiday() is based on the work done by
// Marcos J. Montes: http://www.smart.net/~mmontes/ushols.html
//
// if $week is not passed in, then we are checking for the last week of the month
function get_holiday($year$month$day_of_week$week="") {
    if ( ((
$week != "") && (($week 5) || ($week 1))) || ($day_of_week 6) || ($day_of_week 0) ) {
        
// $day_of_week must be between 0 and 6 (Sun=0, ... Sat=6); $week must be between 1 and 5
        
return FALSE;
    } else {
        if (!
$week || ($week == "")) {
            
$lastday date("t"mktime(0,0,0,$month,1,$year));
            
$temp = (date("w",mktime(0,0,0,$month,$lastday,$year)) - $day_of_week) % 7;
        } else {
            
$temp = ($day_of_week date("w",mktime(0,0,0,$month,1,$year))) % 7;
        }
        
        if (
$temp 0) {
            
$temp += 7;
        }

        if (!
$week || ($week == "")) {
            
$day $lastday $temp;
        } else {
            
$day = ($week) - $temp;
        }

        return 
format_date($year$month$day);
    }
}

function 
observed_day($year$month$day) {
    
// sat -> fri & sun -> mon, any exceptions?
    //
    // should check $lastday for bumping forward and $firstday for bumping back,
    // although New Year's & Easter look to be the only holidays that potentially
    // move to a different month, and both are accounted for.

    
$dow date("w"mktime(000$month$day$year));
    
    if (
$dow == 0) {
        
$dow $day 1;
    } elseif (
$dow == 6) {
        if ((
$month == 1) && ($day == 1)) {    // New Year's on a Saturday
            
$year--;
            
$month 12;
            
$dow 31;
        } else {
            
$dow $day 1;
        }
    } else {
        
$dow $day;
    }

    return 
format_date($year$month$dow);
}

function 
calculate_easter($y) {
    
// In the text below, 'intval($var1/$var2)' represents an integer division neglecting
    // the remainder, while % is division keeping only the remainder. So 30/7=4, and 30%7=2
    //
    // This algorithm is from Practical Astronomy With Your Calculator, 2nd Edition by Peter
    // Duffett-Smith. It was originally from Butcher's Ecclesiastical Calendar, published in
    // 1876. This algorithm has also been published in the 1922 book General Astronomy by
    // Spencer Jones; in The Journal of the British Astronomical Association (Vol.88, page
    // 91, December 1977); and in Astronomical Algorithms (1991) by Jean Meeus. 

    
$a $y%19;
    
$b intval($y/100);
    
$c $y%100;
    
$d intval($b/4);
    
$e $b%4;
    
$f intval(($b+8)/25);
    
$g intval(($b-$f+1)/3);
    
$h = (19*$a+$b-$d-$g+15)%30;
    
$i intval($c/4);
    
$k $c%4;
    
$l = (32+2*$e+2*$i-$h-$k)%7;
    
$m intval(($a+11*$h+22*$l)/451);
    
$p = ($h+$l-7*$m+114)%31;
    
$EasterMonth intval(($h+$l-7*$m+114)/31);    // [3 = March, 4 = April]
    
$EasterDay $p+1;    // (day in Easter Month)
    
    
return format_date($y$EasterMonth$EasterDay);
}

/////////////////////////////////////////////////////////////////////////////
// end of calculation functions; place the dates you wish to calculate below
/////////////////////////////////////////////////////////////////////////////

?>

<form action="<?php echo($PHP_SELF); ?>" method="get">
<b>Enter a Year:</b> <input type="text" name="y" value="<?php echo ($_GET["y"]); ?>" size="4" maxlength="4"> <input type="submit" value="Go">
</form>

<?php

// format to use:
//
// get_holiday("year", "month", "day_of_week", "week_of_month");
// get_holiday("year", "month", "day_of_week);    // no 4th field indicates last week of month check
// format_date("year", "month", "day");

echo "<p><b>". $_GET["y"] ." Holidays</b></p>";
echo 
"<ul>";

echo 
"<li>New Year's Day = "format_date($_GET["y"]11);
    echo 
"<br>New Year's Day Observed = "observed_day($_GET["y"]11);
echo 
"<li>Martin Luther King Day Observed (Third Monday in January) = "get_holiday($_GET["y"]113);
echo 
"<li>Valentine's Day = "format_date($_GET["y"]214);
echo 
"<li>President's Day Observed (Third Monday in February) = "get_holiday($_GET["y"]213);
echo 
"<li>St. Patrick's Day = "format_date($_GET["y"]317);
echo 
"<li>Easter = "calculate_easter($_GET["y"]);
echo 
"<li>Cinco De Mayo = "format_date($_GET["y"]55);
echo 
"<li>Memorial Day Observed (Last Monday in May) = "get_holiday($_GET["y"]51);
echo 
"<li>Independence Day = "format_date($_GET["y"]74);
    echo 
"<br>Independence Day Observed = "observed_day($_GET["y"]74);
echo 
"<li>Labor Day Observed (First Monday in September) = "get_holiday($_GET["y"]911);
echo 
"<li>Columbus Day Observed (Second Monday in October) = "get_holiday($_GET["y"]1012);
echo 
"<li>Halloween = "format_date($_GET["y"]1031);
// Veteran's Day Observed - November 11th ?
echo "<li>Thanksgiving (Fourth Thursday in November) = "get_holiday($_GET["y"]1144);
echo 
"<li>Christmas Day = "format_date($_GET["y"]1225);

echo 
"</ul>";

?>


Alternative Calculations:

function get_holiday($year$month$day_of_week$week_of_month) {
    
// i.e. find the 3rd Monday in January, 2000

    
if (($week_of_month 5) || ($week_of_month 1) || ($day_of_week 6) || ($day_of_week 0)) {
        
// should check any month/week combo first against $lastday...
        
return FALSE;
    } else {
        
$firstday date("w"mktime(000$month1$year));
        
$lastday date("t"mktime(000$month1$year));

        
// start by finding the first occurence in the month of that $day_of_week #
        // then add appropriate number of weeks

        
if ($firstday $day_of_week) {
            
// means we need to jump to the second week to find the first $day_of_week
            
$diff = ($firstday $day_of_week);
            
$first_dow = ($diff) + 1;
            
$day $first_dow + (($week_of_month 7) - 7);
        } elseif (
$firstday $day_of_week) {
            
// correct week, now move forward to specified day
            
$day = ($day_of_week $firstday 1) + (($week_of_month 7) - 7);
        } else {
            
// correct day in first week ($firstday = $day_of_week)
            
$day + (($week_of_month 7) - 7);
        }
        
$date format_date($year$month$day);
        return 
$date;
    }
}

function 
count_dows_in_month($year$month$day_of_week) {
    
// count how many weeks in the month have a specified day, such as Monday.
    // we know there will be 4 or 5, so no need to check for $weeks<4 or $weeks>5

    
$firstday date("w"mktime(000$month1$year));
    
$lastday date("t"mktime(000$month1$year));

    if (
$firstday $day_of_week) {
        
// means we need to jump to the second week to find the first $day_of_week
        
$d = (- ($firstday $day_of_week)) + 1;
    } elseif (
$firstday $day_of_week) {
        
// correct week, now move forward to specified day
        
$d = ($day_of_week $firstday 1);
    } else {    
// $firstday = $day_of_week
        // correct day in first week
        
$d = ($firstday 1);
    }

    
$d += 28;    // jump to the 5th week and see if the day exists
    
if ($d $lastday) {
        
$weeks 4;
    } else {
        
$weeks 5;
    }
    return 
$weeks;
}

To Use Alternative Calculations: count_dows_in_month() will tell you the number of weeks in a given month, which can then be fed into the alternative get_holiday() to determine something like the last Monday in May, i.e. Memorial Day.



Home | Services | Pricing | Portfolio | About Us | Contact
Support | Programs | Purchase | Tutorials | Site Map

© 1999-2024 AbleDesign.com - Web Design that Can!