Fork me on GitHub

A Holiday Library in PHP

Some time ago, I wrote a library to work with US holiday dates. Since a number of the holidays are floating holidays (i.e., the last Monday in May), it's handy to have a library to calculate the dates for those holidays.

One of the better uses I've found is to allow the excluding of holiday dates from the jQuery UI date picker. In this post, I'll explain a little about the library and give detail of how it can be used with the jQuery datepicker.

The following holidays are included by default:

  • New Year's Day (1/1)
  • Independence Day (7/4)
  • Veteran's Day (11/11)
  • Christmas Day (12/25)
  • MLK Day (3rd Mon of Jan)
  • President's Day (3rd Mon. of Feb.)
  • Memorial Day (Last Mon. of May)
  • Labor Day (1st Mon. of Sep.)
  • Columbus Day (2nd Mon. of Oct.)
  • Thanksgiving Day (4th Thurs. of Nov.)

Easter and Good Friday can be included using options. Any other days can be included by passing an array of extra holidays to the library.

I have also made the library available as a CodeIgniter library, [available at GitHub]. Viewing the readme will give you more technical details about the library and the options available with it.

As an example of using the library, we'll walk through using it with the jQuery UI date picker. If you have a form on a website, it would be nice to be able to trust the user to enter valid, logical information, but that generally doesn't happen. So if we're going to put a date picker on a form and don't want the user to select days where the business will be closed, why not disable those days from being selected.

Below is a date picker field with days in the past, weekends, and holidays disabled. For fun, we'll add a couple extra days to disable: the Friday before Memorial Day and the Friday after Thanksgiving.

You can download the library with examples at GitHub.

Step 1:

Set up the HTML page with the date picker field.



    
        
        
        
        
        
        
    
    
        
        
    

Step 2:

Add the javascript file for the date picker.

In it's basic form, we just need a couple lines to get the date picker going:

$(function(){
    
    $("#holiday-picker").datepicker();
    
});

We can add options to prevent the showing of days in the past:

$(function(){
    
    $("#holiday-picker").datepicker( { minDate: 0 } );
    
});

To disable weekends and holidays, we need a few extra functions:

$(function(){
    
    $("#holiday-picker").datepicker({
          minDate: 0, 
          beforeShowDay: noWeekendsOrHolidays
    });
    
});

//the script that will give us the holiday dates
var holidayScript = 'get_dates.php';

//Today's date
var nowish        = new Date();

//This year
usHolidays.year   = nowish.getFullYear();

//Set the holidays
setHolidays(usHolidays.year);

//call the PHP script to get the dates for the selected year
function setHolidays(selYear){
    $.ajax({
        url: holidayScript,
        data: {year: selYear},
        dataType: "json",
        async: false, //while this is not generally good practice, it works here
        success: function(data){
            usHolidays.holidays = data;
        }
    });
}

//The function used by the date picker
function noWeekendsOrHolidays(date){
    var noWeekend = $.datepicker.noWeekends(date);
    
    if(noWeekend[0]){
        return usHolidays(date); 
    } else {
        return noWeekend;
    }
}

//Helper function to determine if current date is a holiday
function usHolidays(date){
    var d = date.getDate();
    var m = date.getMonth() + 1;
    var y = date.getFullYear();
    
    if(y != usHolidays.year){
        setHolidays(y);
        usHolidays.year = y;
    }
    
    for(i = 0; i < usHolidays.holidays.length; i++){
        if(m == usHolidays.holidays[i][0] && d == usHolidays.holidays[i][1]){
            return [false, ""];
        }
    }
    
    return [true, ""];
}

Step 3:

Build the Ajax Script

Thanks to the library, the AJAX script is very simple:

<?php

    require_once('Holidays.class.php');

    $extras = array(
        'Fri. before Memorial Day' => array(-5, 1, 5, 5),
        'Fri. after Thanksgiving'  => array(+5, 4, 11, 4)
    );

    //Instantiate the object
    $holidays = new Holidays($extras);

    //Get the year from the request array
    $year  = $_REQUEST['year'];

    //set the year
    $holidays->setYear($year);

    //set the content type
    header('Content-type: application/json');

    //output the json
    echo $holidays->getJson();

    exit();

You can see where we set the extra days in the array (see the docs on GitHub for more explanation on that), set the year, and get the data in JSON format.

Hopefully this library prove useful to you. If there is a feature that isn't there that you would like to see added, let me know and I'll see what I can do.

Get the library for PHP on GitHub

Get the CodeIgniter library on GitHub