Created
November 26, 2018 16:45
-
-
Save rinogo/eec3c121613d7080439f9cbc1101387d to your computer and use it in GitHub Desktop.
Simple unit-tested class to calculate federal holiday dates for the United States. Methods are included for determining if a date (timestamp) is considered a date and for accessing holidays by name and by timestamp.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//Adapted by rich at byu.net from https://www.damia.no/calculating-u-s-federal-holidays-with-php/ | |
class UsHolidays { | |
private $year; | |
private $list; | |
const ONE_DAY = 86400; //Number of seconds in one day | |
function __construct($year = null, $timezone = "America/Denver") { | |
try { | |
$original_time_zone = date_default_timezone_get(); | |
if(!date_default_timezone_set($timezone)) { | |
throw new Exception("$timezone is not a valid timezone."); | |
} | |
$this->year = (is_null($year)) ? (int) date("Y") : (int) $year; | |
if(!is_int($this->year) || $this->year < 1997) { | |
throw new Exception("$year is not a valid year. Valid values are integers greater than 1996."); | |
} | |
$this->setList(); | |
} finally { | |
date_default_timezone_set($original_time_zone); | |
} | |
} | |
private function adjustFixedHoliday($timestamp) { | |
$weekday = date("w", $timestamp); | |
if($weekday == 0) { | |
return $timestamp + self::ONE_DAY; //NOTE: Potential daylight savings issue for holidays that coincide with/are adjacent to daylight savings "transition" dates? | |
} | |
if($weekday == 6) { | |
return $timestamp - self::ONE_DAY; //NOTE: Potential daylight savings issue for holidays that coincide with/are adjacent to daylight savings "transition" dates? | |
} | |
return $timestamp; | |
} | |
private function setList() { | |
$this->list = array(); | |
$this->list[$this->adjustFixedHoliday(mktime(0, 0, 0, 1, 1, $this->year))] = "New Year's Day"; //January 1st (if not Saturday/Sunday) | |
$this->list[strtotime("Third Monday of January $this->year")] = "Martin Luther King, Jr. Day"; //3rd Monday of January | |
$this->list[strtotime("Third Monday of February $this->year")] = "Presidents' Day"; //3rd Monday of February | |
$this->list[strtotime("Last Monday of May $this->year")] = "Memorial Day"; //Last Monday of May | |
$this->list[$this->adjustFixedHoliday(mktime(0, 0, 0, 7, 4, $this->year))] = "Independence Day"; //July 4 (if not Saturday/Sunday) | |
$this->list[strtotime("First Monday of September $this->year")] = "Labor Day"; //1st Monday of September | |
$this->list[strtotime("Second Monday of October $this->year")] = "Columbus Day"; //2nd Monday of October | |
$this->list[$this->adjustFixedHoliday(mktime(0, 0, 0, 11, 11, $this->year))] = "Veterans Day"; //November 11 (if not Saturday/Sunday) | |
$this->list[strtotime("Fourth Thursday of November $this->year")] = "Thanksgiving Day"; //4th Thursday of November | |
$this->list[$this->adjustFixedHoliday(mktime(0, 0, 0, 12, 25, $this->year))] = "Christmas Day"; //December 25 every year (if not Saturday/Sunday) | |
} | |
public function getList() { | |
return $this->list; | |
} | |
public function getListByName() { | |
return array_flip($this->list); | |
} | |
public function isHoliday($timestamp) { | |
return array_key_exists($timestamp, $this->list); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class UsHolidaysTest extends PHPUnit_Framework_TestCase { | |
/** | |
* @group unit | |
*/ | |
public function testGetList() { | |
$offset = get_timezone_offset("America/Denver"); | |
//2013 | |
$holidays = new UsHolidays(2013); | |
$list = $holidays->getList(); | |
$this->assertEquals($list[get_date_time("1/1/2013")], "New Year's Day"); | |
$this->assertEquals($list[get_date_time("1/21/2013")], "Martin Luther King, Jr. Day"); | |
$this->assertEquals($list[get_date_time("2/18/2013")], "Presidents' Day"); | |
$this->assertEquals($list[get_date_time("5/27/2013")], "Memorial Day"); | |
$this->assertEquals($list[get_date_time("7/4/2013")], "Independence Day"); | |
$this->assertEquals($list[get_date_time("9/2/2013")], "Labor Day"); | |
$this->assertEquals($list[get_date_time("10/14/2013")], "Columbus Day"); | |
$this->assertEquals($list[get_date_time("11/11/2013")], "Veterans Day"); | |
$this->assertEquals($list[get_date_time("11/28/2013")], "Thanksgiving Day"); | |
$this->assertEquals($list[get_date_time("12/25/2013")], "Christmas Day"); | |
//2014 | |
$holidays = new UsHolidays(2014); | |
$list = $holidays->getList(); | |
$this->assertEquals($list[get_date_time("1/1/2014")], "New Year's Day"); | |
$this->assertEquals($list[get_date_time("1/20/2014")], "Martin Luther King, Jr. Day"); | |
$this->assertEquals($list[get_date_time("2/17/2014")], "Presidents' Day"); | |
$this->assertEquals($list[get_date_time("5/26/2014")], "Memorial Day"); | |
$this->assertEquals($list[get_date_time("7/4/2014")], "Independence Day"); | |
$this->assertEquals($list[get_date_time("9/1/2014")], "Labor Day"); | |
$this->assertEquals($list[get_date_time("10/13/2014")], "Columbus Day"); | |
$this->assertEquals($list[get_date_time("11/11/2014")], "Veterans Day"); | |
$this->assertEquals($list[get_date_time("11/27/2014")], "Thanksgiving Day"); | |
$this->assertEquals($list[get_date_time("12/25/2014")], "Christmas Day"); | |
//2015 | |
$holidays = new UsHolidays(2015); | |
$list = $holidays->getList(); | |
$this->assertEquals($list[get_date_time("1/1/2015")], "New Year's Day"); | |
$this->assertEquals($list[get_date_time("1/19/2015")], "Martin Luther King, Jr. Day"); | |
$this->assertEquals($list[get_date_time("2/16/2015")], "Presidents' Day"); | |
$this->assertEquals($list[get_date_time("5/25/2015")], "Memorial Day"); | |
$this->assertEquals($list[get_date_time("7/3/2015")], "Independence Day"); | |
$this->assertEquals($list[get_date_time("9/7/2015")], "Labor Day"); | |
$this->assertEquals($list[get_date_time("10/12/2015")], "Columbus Day"); | |
$this->assertEquals($list[get_date_time("11/11/2015")], "Veterans Day"); | |
$this->assertEquals($list[get_date_time("11/26/2015")], "Thanksgiving Day"); | |
$this->assertEquals($list[get_date_time("12/25/2015")], "Christmas Day"); | |
//2016 | |
$holidays = new UsHolidays(2016); | |
$list = $holidays->getList(); | |
$this->assertEquals($list[get_date_time("1/1/2016")], "New Year's Day"); | |
$this->assertEquals($list[get_date_time("1/18/2016")], "Martin Luther King, Jr. Day"); | |
$this->assertEquals($list[get_date_time("2/15/2016")], "Presidents' Day"); | |
$this->assertEquals($list[get_date_time("5/30/2016")], "Memorial Day"); | |
$this->assertEquals($list[get_date_time("7/4/2016")], "Independence Day"); | |
$this->assertEquals($list[get_date_time("9/5/2016")], "Labor Day"); | |
$this->assertEquals($list[get_date_time("10/10/2016")], "Columbus Day"); | |
$this->assertEquals($list[get_date_time("11/11/2016")], "Veterans Day"); | |
$this->assertEquals($list[get_date_time("11/24/2016")], "Thanksgiving Day"); | |
$this->assertEquals($list[get_date_time("12/26/2016")], "Christmas Day"); | |
//2017 | |
$holidays = new UsHolidays(2017); | |
$list = $holidays->getList(); | |
$this->assertEquals($list[get_date_time("1/2/2017")], "New Year's Day"); | |
$this->assertEquals($list[get_date_time("1/16/2017")], "Martin Luther King, Jr. Day"); | |
$this->assertEquals($list[get_date_time("2/20/2017")], "Presidents' Day"); | |
$this->assertEquals($list[get_date_time("5/29/2017")], "Memorial Day"); | |
$this->assertEquals($list[get_date_time("7/4/2017")], "Independence Day"); | |
$this->assertEquals($list[get_date_time("9/4/2017")], "Labor Day"); | |
$this->assertEquals($list[get_date_time("10/9/2017")], "Columbus Day"); | |
$this->assertEquals($list[get_date_time("11/10/2017")], "Veterans Day"); | |
$this->assertEquals($list[get_date_time("11/23/2017")], "Thanksgiving Day"); | |
$this->assertEquals($list[get_date_time("12/25/2017")], "Christmas Day"); | |
//2018 | |
$holidays = new UsHolidays(2018); | |
$list = $holidays->getList(); | |
$this->assertEquals($list[get_date_time("1/1/2018")], "New Year's Day"); | |
$this->assertEquals($list[get_date_time("1/15/2018")], "Martin Luther King, Jr. Day"); | |
$this->assertEquals($list[get_date_time("2/19/2018")], "Presidents' Day"); | |
$this->assertEquals($list[get_date_time("5/28/2018")], "Memorial Day"); | |
$this->assertEquals($list[get_date_time("7/4/2018")], "Independence Day"); | |
$this->assertEquals($list[get_date_time("9/3/2018")], "Labor Day"); | |
$this->assertEquals($list[get_date_time("10/8/2018")], "Columbus Day"); | |
$this->assertEquals($list[get_date_time("11/12/2018")], "Veterans Day"); | |
$this->assertEquals($list[get_date_time("11/22/2018")], "Thanksgiving Day"); | |
$this->assertEquals($list[get_date_time("12/25/2018")], "Christmas Day"); | |
//2019 | |
$holidays = new UsHolidays(2019); | |
$list = $holidays->getList(); | |
$this->assertEquals($list[get_date_time("1/1/2019")], "New Year's Day"); | |
$this->assertEquals($list[get_date_time("1/21/2019")], "Martin Luther King, Jr. Day"); | |
$this->assertEquals($list[get_date_time("2/18/2019")], "Presidents' Day"); | |
$this->assertEquals($list[get_date_time("5/27/2019")], "Memorial Day"); | |
$this->assertEquals($list[get_date_time("7/4/2019")], "Independence Day"); | |
$this->assertEquals($list[get_date_time("9/2/2019")], "Labor Day"); | |
$this->assertEquals($list[get_date_time("10/14/2019")], "Columbus Day"); | |
$this->assertEquals($list[get_date_time("11/11/2019")], "Veterans Day"); | |
$this->assertEquals($list[get_date_time("11/28/2019")], "Thanksgiving Day"); | |
$this->assertEquals($list[get_date_time("12/25/2019")], "Christmas Day"); | |
//2020 | |
$holidays = new UsHolidays(2020); | |
$list = $holidays->getList(); | |
$this->assertEquals($list[get_date_time("1/1/2020")], "New Year's Day"); | |
$this->assertEquals($list[get_date_time("1/20/2020")], "Martin Luther King, Jr. Day"); | |
$this->assertEquals($list[get_date_time("2/17/2020")], "Presidents' Day"); | |
$this->assertEquals($list[get_date_time("5/25/2020")], "Memorial Day"); | |
$this->assertEquals($list[get_date_time("7/3/2020")], "Independence Day"); | |
$this->assertEquals($list[get_date_time("9/7/2020")], "Labor Day"); | |
$this->assertEquals($list[get_date_time("10/12/2020")], "Columbus Day"); | |
$this->assertEquals($list[get_date_time("11/11/2020")], "Veterans Day"); | |
$this->assertEquals($list[get_date_time("11/26/2020")], "Thanksgiving Day"); | |
$this->assertEquals($list[get_date_time("12/25/2020")], "Christmas Day"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//Convert a date in the format mm/dd/yyyy to its equivalent time in seconds since the Unix Epoch. | |
function get_date_time($date, $timezone_str = "America/Denver") { | |
$tokens = explode("/", $date); | |
$timezone = new DateTimeZone($timezone_str); | |
$dt = DateTime::createFromFormat("!m/d/Y", date("m/d/Y", mktime(0, 0, 0, $tokens[0], $tokens[1], $tokens[2])), $timezone); | |
return $dt->getTimestamp(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment