© 2008 Michael Thompson
Algorithm for Calculating
[ Main Index ]
|
| Holiday | Definition | |
|---|---|---|
| ML King | 3rd Monday of Jan | Mon, Jan 21st |
| Presidents Day | 3rd Monday of Feb | Mon, Feb 18th |
| Memorial Day | Last Monday of May | Mon, May 26th1 |
| Labor Day | 1st Monday of Sep | Mon, Sep 1st |
| Columbus Day | 2nd Monday of Oct | Mon, Oct 13th |
| Election Day | Tuesday after 1st Monday of Nov |
Tue, Nov 4th2 |
| Thanksgiving Day | 4th Thursday of Nov | Thu, Nov 27th |
To determine the date of a floating holiday for a given year, i.e. the date of a holiday that occurs on the first Monday of the month (like Presidents Day) or a holiday that occurs on the fourth Thursday of the month (Thanksgiving)
nTargetday=1 nMonth=2 nYear=2003
nEarliestDate = 1 + 7 * (nTh - 1)where nTh is the number of the occurence of the target day, i.e. given "the third Friday", nTh=3; given "the first Monday" nTh=1
$nWeekday = date("w",mktime(0,0,0,$nMonth,$nEarliestDate,$nYear));
in Java/Javascript:
d = new date(nYear,nMonth,nEarliestDate); nWeekday = d.getDay();in C:
struct tm mtm; memcpy(&mtm,localtime(time()),sizeof(struct tm)); mtm.tm_mon = 1 + nMonth; mtm.tm_mday = nEarliestDate; mtm.tm_year = nYear - 1900; mktime(&mtm); nWeekday = mtm.tm_wday;(Note: If you need a version that works for 2038 through 2105 use a 64-bit version of mktime)
if( nTargetday==nWeekday ) nOffset = 0;
else
{
if( nTargetday<nWeekday ) nOffset = nTargetday + (7 - nWeekday);
else nOffset = (nTargetday + (7 - nWeekday)) - 7;
}
in PHP:
$tHolidayDate = mktime(0,0,0,$nMonth,$nEarliestDate + $nOffset,$nYear);in Java/Javascript:
tHolidayDate = new date(nYear,nMonth,nEarliestDate + nOffset);in C:
mtm.tm_mon = 1 + nMonth; mtm.tm_mday = nEarliestDate + nOffset; mtm.tm_year = nYear - 1900; tHolidayDate = mktime(&mtm);
To follow the rule "last Monday in May" we calculate the fourth Monday as shown above and then add one week if there are five Mondays in May.
To follow the rule "the Tuesday after the first Monday in November" we calculate the first Monday as shown above and then add one day.