<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* USA.php
*
* PHP Version 4
*
* Copyright (c) 1997-2008 The PHP Group
*
* This source file is subject to version 3.0 of the PHP license,
* that is bundled with this package in the file LICENSE, and is
* available at through the world-wide-web at
* http://www.php.net/license/3_01.txt.
* If you did not receive a copy of the PHP license and are unable to
* obtain it through the world-wide-web, please send a note to
* license@php.net so we can mail you a copy immediately.
*
* @category Date
* @package Date_Holidays
* @author Kevin English <kevin@x5dev.com>
* @license http://www.php.net/license/3_01.txt PHP License 3.0.1
* @version CVS: $Id: USA.php,v 1.11 2008/03/17 11:37:49 kguest Exp $
* @link http://pear.php.net/package/Date_Holidays
*/
//
/**
* class that calculates observed U.S. holidays
*
* @category Date
* @package Date_Holidays
* @subpackage Driver
* @author Kevin English <kevin@x5dev.com>
* @license http://www.php.net/license/3_01.txt PHP License 3.0.1
* @version CVS: $Id: USA.php,v 1.11 2008/03/17 11:37:49 kguest Exp $
* @link http://pear.php.net/package/Date_Holidays
*/
class Date_Holidays_Driver_USA extends Date_Holidays_Driver
{
/**
* Constructor
*
* Use the Date_Holidays::factory() method to construct an object of a
* certain driver
*
* @access protected
*/
function Date_Holidays_Driver_USA()
{
}
/**
* Build the internal arrays that contain data about the calculated holidays
*
* @access protected
* @return boolean true on success, otherwise a PEAR_ErrorStack object
* @throws object PEAR_ErrorStack
*/
function _buildHolidays()
{
/**
* New Year's Day
*/
$newYearsDay = $this->_calcNearestWorkDay('01', '01');
$this->_addHoliday('newYearsDay', $newYearsDay, 'New Year\'s Day');
$thirdMondayInJanuaryDate = $this->_calcNthMondayInMonth(1, 3);
$this->_addHoliday('mlkDay',
$thirdMondayInJanuaryDate,
'Dr. Martin Luther King Jr\'s Birthday');
/**
* President's Day
*/
$thirdMondayInFebruaryDate = $this->_calcNthMondayInMonth(2, 3);
$this->_addHoliday('presidentsDay',
$thirdMondayInFebruaryDate,
'President\'s Day');
/**
* Memorial Day
*/
$lastMondayInMayDate = $this->_calcLastMondayInMonth(5);
$this->_addHoliday('memorialDay', $lastMondayInMayDate, 'Memorial Day');
/**
* 4th of July
*/
$independenceDay = $this->_calcNearestWorkDay('07', '04');
$this->_addHoliday('independenceDay', $independenceDay, 'Independence Day');
/**
* Labor Day
*/
$laborDay = $this->_calcNthMondayInMonth(9, 1);
$this->_addHoliday('laborDay', $laborDay, 'Labor Day');
/**
* Columbus Day
*/
$columbusDay = $this->_calcNthMondayInMonth(10, 2);
$this->_addHoliday('columbusDay', $columbusDay, 'Columbus Day');
/**
* Veteran's Day
*/
$this->_addHoliday('veteransDay', $this->_year.'-11-11', 'Veteran\'s Day');
/**
* Thanksgiving Day
*/
$tday = $this->_calcNthThursdayInMonth(11, 4);
$this->_addHoliday('thanksgivingDay', $tday, 'Thanksgiving Day');
/**
* Christmas Day
*/
$cday = $this->_calcNearestWorkDay('12', '25');
$this->_addHoliday('christmasDay', $cday, 'Christmas Day');
return true;
}
/**
* Calculate Nth monday in a month
*
* @param int $month month
* @param int $position position
*
* @access private
* @return object Date date
*/
function _calcNthMondayInMonth($month, $position)
{
if ($position == 1) {
$startday = '01';
} elseif ($position == 2) {
$startday = '08';
} elseif ($position == 3) {
$startday = '15';
} elseif ($position == 4) {
$startday = '22';
} elseif ($position == 5) {
$startday = '29';
}
$month = sprintf("%02d", $month);
$date = new Date($this->_year . '-' . $month . '-' . $startday);
while ($date->getDayOfWeek() != 1) {
$date = $date->getNextDay();
}
return $date;
}
/**
* Calculate Nth thursday in a month
*
* @param int $month month
* @param int $position position
*
* @access private
* @return object Date date
*/
function _calcNthThursdayInMonth($month, $position)
{
if ($position == 1) {
$startday = '01';
} elseif ($position == 2) {
$startday = '08';
} elseif ($position == 3) {
$startday = '15';
} elseif ($position == 4) {
$startday = '22';
} elseif ($position == 5) {
$startday = '29';
}
$month = sprintf("%02d", $month);
$date = new Date($this->_year . '-' . $month . '-' . $startday);
while ($date->getDayOfWeek() != 4) {
$date = $date->getNextDay();
}
return $date;
}
/**
* Calculate last monday in a month
*
* @param int $month month
*
* @access private
* @return object Date date
*/
function _calcLastMondayInMonth($month)
{
$month = sprintf("%02d", $month);
$date = new Date($this->_year . '-' . $month . '-01');
$daysInMonth = $date->getDaysInMonth();
$date = new Date($this->_year . '-' . $month . '-' . $daysInMonth);
while ($date->getDayOfWeek() != 1) {
$date = $date->getPrevDay();
}
return $date;
}
/**
* Calculate nearest workday for a certain day
*
* @param int $month month
* @param int $day day
*
* @access private
* @return object Date date
*/
function _calcNearestWorkDay($month, $day)
{
$month = sprintf("%02d", $month);
$day = sprintf("%02d", $day);
$date = new Date($this->_year . '-' . $month . '-' . $day);
// When one of these holidays falls on a Saturday, the previous day is
// also a holiday
// When New Year's Day, Independence Day, or Christmas Day falls on a
// Sunday, the next day is also a holiday.
if ($date->getDayOfWeek() == 0 ) {
// bump it up one
$date = $date->getNextDay();
}
if ($date->getDayOfWeek() == 6 ) {
// push it back one
$date = $date->getPrevDay();
}
return $date;
}
/**
* Method that returns an array containing the ISO3166 codes that may possibly
* identify a driver.
*
* @static
* @access public
* @return array possible ISO3166 codes
*/
function getISO3166Codes()
{
return array('us', 'usa');
}
}
?>