祝日・振替休日を取得するには PEAR::Date_Holidays_Japan
にお任せする。
インストールは以下のコマンドで。
# pear install Date_Holidays_Japan-alpha
Calendar クラスの実装は以下のように。
Calendar.class.php
<?php
/**
* カレンダークラス
* Calendar.class.php
*/
final class Calendar
{
/**
* 日曜日
*/
const T_SUNDAY = 0;
/**
* 月曜日
*/
const T_MONDAY = 1;
/**
* 火曜日
*/
const T_TUESDAY = 2;
/**
* 水曜日
*/
const T_WEDNESDAY = 3;
/**
* 木曜日
*/
const T_THURSDAY = 4;
/**
* 金曜日
*/
const T_FRIDAY = 5;
/**
* 土曜日
*/
const T_SATURDAY = 6;
/**
* キャッシュに使用する祝日配列
* @var array(YYYY => array('YYYY-mm-dd' => '祝日名'))
*/
static private $_arrHolidays = array();
/**
* 祝日を取得する
* @param integer $year
* @return array
*/
private static function getHolidays($year)
{
// 取得済みならキャッシュを使う
if (isset(static::$_arrHolidays[$year])) {
return static::$_arrHolidays[$year];
}
// 未取得のとき
$errorLevel = error_reporting(); // エラー出力レベルを取得
error_reporting(E_NOTICE); // PHP Deprecated: Non-static method... を抑止
require_once 'Date/Holidays.php';
$dh = Date_Holidays::factory('Japan', $year, 'ja_JP');
$holidays = array();
foreach ($dh->getHolidays() as $h) {
$holidays[$h->getDate()->format('%Y-%m-%d')] = $h->getTitle();
}
error_reporting($errorLevel); // エラー出力レベルを戻す
ksort($holidays);
static::$_arrHolidays[$year] = $holidays;
return static::$_arrHolidays[$year];
}
/**
* 祝日かどうかを判定する
* @param \DateTime $objDate 判定する日付
* @return bool 祝日ならtrue
*/
public static function isHoliday(\DateTime $objDate)
{
$year = $objDate->format('Y');
$holidays = self::getHolidays($year);
return array_key_exists($objDate->format('Y-m-d'), $holidays);
}
/**
* 定休日かどうかを判定する
* @param \DateTime $objDate 判定する日付
* @return bool 定休日ならtrue
*/
public static function isRegularHoliday(\DateTime $objDate)
{
//定休日リスト
$arrRegularHoliday = array(
self::T_SUNDAY
, self::T_SATURDAY
);
return in_array($objDate->format('w'), $arrRegularHoliday);
}
/**
* ○日後の営業日を取得する
* @param integer $dateAfter 指定しない時は翌営業日を返す
* @param \Datetime $objDate 基準日
* @return \Datetime
*/
public static function getWeekdayAfter($dateAfter = 1, \DateTime $objDate = null)
{
$date = (is_null($objDate)) ? new \DateTime() : $objDate;
$interval = new \DateInterval("P1D");
for ($i = 0; $i < $dateAfter; $i++) {
$date->add($interval);
// 定休日・祝日のときはカウントしないので、$dateAfterをインクリメント
if (self::isRegularHoliday($date) || self::isHoliday($date)) {
$dateAfter++;
}
}
return $date;
}
}
利用する時はこんな感じ。
<?php
require 'Calendar.class.php';
// usage
// 2015-10-10(Friday) -> 2015-10-12(Monday) 体育の日
$res = Calendar::getWeekdayAfter(1, new \DateTime('2015-10-10'));
var_dump($res); // 2015-10-13
// 2015-05-01(金)
// 2015-05-02(土)
// 2015-05-03(日・憲法記念日)
// 2015-05-04(みどりの日)
// 2015-05-05(こどもの日)
// 2015-05-06(振替休日)
$res = Calendar::getWeekdayAfter(1, new \DateTime('2015-05-01'));
var_dump($res); // 2015-05-07