STAFF BLOG スタッフブログ

祝祭日+独自休日を自動判定するphpクラス

昔、祝日になると家の玄関前に
国旗を掲げるお家をよく見かける風景がありましたが
少なくなりましたね。


昔は固定日だったのがハッピーマンデーになったり
海の日ができたと思ったら山の日ができましたね。。。


企業だと年間休日で祝日+創立記念日や夏季休暇・冬季休暇と
固定の日と不定期なお休みがありますよね。

↓↓↓こちらのサイトを参考にさせていただきました。
https://qiita.com/chiyoyo/items/539dc2840a1b70a8e2c3

祝祭日+企業独自の休日チェックのプログラムを
私の方はDBでのチェックタイプで作ってみました。

DBテーブル定義


# DBテーブルの構造
DROP TABLE IF EXISTS `holiday_master`;
CREATE TABLE IF NOT EXISTS `holiday_master` (
  `id` int(11) NOT NULL,
  `type` varchar(100) NOT NULL DEFAULT '' COMMENT '休日区分',
  `date_range1` date NOT NULL DEFAULT '1900-01-01' COMMENT '開始年月日',
  `date_range2` date NOT NULL DEFAULT '9999-12-31' COMMENT '終了年月日',
  `month` tinyint(4) NOT NULL DEFAULT '0' COMMENT '月',
  `day` tinyint(4) NOT NULL DEFAULT '0' COMMENT '日',
  `m_week` tinyint(4) NOT NULL DEFAULT '0' COMMENT '第〇週(区分=regularでゼロの場合は毎週)',
  `week` tinyint(4) NOT NULL DEFAULT '0' COMMENT '週',
  `title` varchar(100) NOT NULL DEFAULT '' COMMENT '休日タイトル',
  `created_at` datetime NOT NULL,
  `modified_at` datetime NOT NULL,
  `del_flg` tinyint(4) NOT NULL DEFAULT '0' COMMENT '削除フラグ 1:削除済み'
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='祝日マスタ';

ALTER TABLE `holiday_master`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `holiday_master`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

# fixed:固定の祝日, happy:ハッピーマンデー, spring:春分の日, autumn:秋分の日, unique:企業独自の創立記念日etcの休日, range:企業独自の冬季休暇・夏期休暇etcの範囲指定休日
INSERT INTO `holiday_master` (`type`, `date_range1`, `date_range2`, `month`, `day`, `m_week`, `week`, `title`, `created_at`, `modified_at`, `del_flg`) VALUES
('fixed',  '1949-01-01', '9999-12-31',  1,  1, 0, 0, '元日', NOW(), NOW(), 0),
('fixed',  '1949-01-01', '1999-12-31',  1, 15, 0, 0, '成人の日', NOW(), NOW(), 0),
('happy',  '2000-01-01', '9999-12-31',  1,  0, 2, 1, '成人の日', NOW(), NOW(), 0),
('fixed',  '1967-01-01', '9999-12-31',  2, 11, 0, 0, '建国記念の日', NOW(), NOW(), 0),
('spring', '1949-01-01', '9999-12-31',  3,  0, 0, 0, '春分の日', NOW(), NOW(), 0),
('fixed',  '1949-01-01', '1989-12-31',  4, 29, 0, 0, '天皇誕生日', NOW(), NOW(), 0),
('fixed',  '1990-01-01', '2006-12-31',  4, 29, 0, 0, 'みどりの日', NOW(), NOW(), 0),
('fixed',  '2007-01-01', '9999-12-31',  4, 29, 0, 0, '昭和の日', NOW(), NOW(), 0),
('fixed',  '1949-01-01', '9999-12-31',  5,  3, 0, 0, '憲法記念日', NOW(), NOW(), 0),
('fixed',  '1988-01-01', '2006-12-31',  5,  4, 0, 0, '国民の休日', NOW(), NOW(), 0),
('fixed',  '2007-01-01', '9999-12-31',  5,  4, 0, 0, 'みどりの日', NOW(), NOW(), 0),
('fixed',  '1949-01-01', '9999-12-31',  5,  5, 0, 0, 'こどもの日', NOW(), NOW(), 0),
('happy',  '2003-01-01', '9999-12-31',  7,  0, 3, 1, '海の日', NOW(), NOW(), 0),
('fixed',  '1996-01-01', '2002-12-31',  7, 20, 0, 0, '海の日', NOW(), NOW(), 0),
('fixed',  '2016-01-01', '9999-12-31',  8, 11, 0, 0, '山の日', NOW(), NOW(), 0),
('autumn', '1948-01-01', '9999-12-31',  9,  0, 0, 0, '秋分の日', NOW(), NOW(), 0),
('fixed',  '1966-01-01', '2002-12-31',  9, 15, 0, 0, '敬老の日', NOW(), NOW(), 0),
('happy',  '2003-01-01', '9999-12-31',  9,  0, 3, 1, '敬老の日', NOW(), NOW(), 0),
('fixed',  '1966-01-01', '1999-12-31', 10, 10, 0, 0, '体育の日', NOW(), NOW(), 0),
('happy',  '2000-01-01', '9999-12-31', 10,  0, 2, 1, '体育の日', NOW(), NOW(), 0),
('fixed',  '1948-01-01', '9999-12-31', 11,  3, 0, 0, '文化の日', NOW(), NOW(), 0),
('fixed',  '1948-01-01', '9999-12-31', 11, 23, 0, 0, '勤労感謝の日', NOW(), NOW(), 0),
('fixed',  '1989-01-01', '9999-12-31', 12, 23, 0, 0, '天皇誕生日', NOW(), NOW(), 0),
('fixed',  '1959-04-10', '1959-04-10',  4, 10, 0, 0, '皇太子明仁親王の結婚の儀', NOW(), NOW(), 0),
('fixed',  '1989-02-24', '1989-02-24',  2, 24, 0, 0, '昭和天皇の大喪の礼', NOW(), NOW(), 0),
('fixed',  '1990-11-12', '1990-11-12', 11, 12, 0, 0, '即位礼正殿の儀', NOW(), NOW(), 0),
('fixed',  '1993-01-01', '1993-12-31',  6,  9, 0, 0, '皇太子徳仁親王の結婚の儀', NOW(), NOW(), 0),
('unique', '2000-01-01', '9999-12-31',  3, 10, 0, 0, '創立記念日', NOW(), NOW(), 0),
('range',  '2017-12-28', '2018-01-08',  0,  0, 0, 0, '冬季休暇', NOW(), NOW(), 0);

FuelPHPのModelクラス


<?php
// 祝祭日マスタ
class Model_Holiday_Master extends \Model_Crud
{
	// テーブル名
	protected static $_table_name = 'holiday_master';

	// 初期値
	protected static $_defaults = array(
		'type'            => '',
		'date_range1'     => null,
		'date_range2'     => null,
		'month'           => 0,
		'day'             => 0,
		'm_week'          => 0,
		'week'            => 0,
		'title'           => '',
		'created_at'      => '',
		'created_user'    => 0,
		'modified_at'     => '',
		'modified_user'   => 0,
	);

	const TYPE_UNIQUE  = 'unique';
	const TYPE_RANGE   = 'range';
	const TYPE_FIXED   = 'fixed';
	const TYPE_HAPPY   = 'happy';
	const TYPE_SPRING  = 'spring';
	const TYPE_AUTUMN  = 'autumn';
	static $TYPE = array(
		self::TYPE_UNIQUE   => '企業独自の創立記念日等の固定休日',
		self::TYPE_RANGE    => '企業独自の冬季休暇・夏期休暇等の範囲指定休日',
		self::TYPE_FIXED    => '固定の祝日',
		self::TYPE_HAPPY    => 'ハッピーマンデー',
		self::TYPE_SPRING   => '春分の日',
		self::TYPE_AUTUMN   => '秋分の日',
	);


	// 創立記念日等の休日チェック
	public static function check_unique_holiday($dt = null)
	{
		$dt  = new \DateTime($dt);

		$param = array(
			'where'  => array(
				array('type', '=', self::TYPE_UNIQUE),
				array('date_range1', '<=', $dt->format('Y-m-d')),
				array('date_range2', '>=', $dt->format('Y-m-d')),
				array('month', '=', $dt->format('n')),
				array('day', '=', $dt->format('j')),
			)
		);
		$list = self::find($param);
		if ( $list )
		{
			return $list[0]->title;
		}

		return false;
	}


	// 夏季休暇・冬季休暇の休日チェック
	public static function check_range_holiday($dt = null)
	{
		$dt  = new \DateTime($dt);

		$param = array(
			'where'  => array(
				array('type', '=', self::TYPE_RANGE),
				array('date_range1', '<=', $dt->format('Y-m-d')),
				array('date_range2', '>=', $dt->format('Y-m-d')),
			)
		);
		$list = self::find($param);
		if ( $list )
		{
			return $list[0]->title;
		}

		return false;
	}


	// 固定の休日チェック
	public static function check_fixed_holiday($dt = null)
	{
		$dt  = new \DateTime($dt);

		$param = array(
			'where'  => array(
				array('type', '=', self::TYPE_FIXED),
				array('date_range1', '<=', $dt->format('Y-m-d')),
				array('date_range2', '>=', $dt->format('Y-m-d')),
				array('month', '=', $dt->format('n')),
				array('day', '=', $dt->format('j')),
			)
		);
		$list = self::find($param);
		if ( $list )
		{
			return $list[0]->title;
		}

		return false;
	}


	// ハッピーマンデーチェック
	public static function check_happy_holiday($dt = null)
	{
		$dt  = new \DateTime($dt);

		$param = array(
			'where'  => array(
				array('type', '=', self::TYPE_HAPPY),
				array('date_range1', '<=', $dt->format('Y-m-d')),
				array('date_range2', '>=', $dt->format('Y-m-d')),
				array('month', '=', $dt->format('n')),
			)
		);
		$list = self::find($param);
		if ( $list )
		{
			// 第*月曜日の日付を求める
			$w = $list[0]->week; // 指定曜日対応
			$first = new \DateTime($dt->format('Y-m').'-01');
			$fw = $first->format('w');
			$day = $w - $fw < 0 ? 7 + $w - $fw : $w - $fw;
			$day++;
			$day = $day + 7 * ( $list[0]->m_week - 1 );
			if ( $dt->format('j') == $day )
			{
				return $list[0]->title;
			}
		}

		return false;
	}


	// 春分の日チェック
	public static function check_spring_holiday($dt = null)
	{
		$dt  = new \DateTime($dt);

		$param = array(
			'where'  => array(
				array('type', '=', self::TYPE_SPRING),
				array('date_range1', '<=', $dt->format('Y-m-d')),
				array('date_range2', '>=', $dt->format('Y-m-d')),
				array('month', '=', $dt->format('n')),
			)
		);
		$list = self::find($param);
		if ( $list )
		{
			$year = $dt->format('Y');
			$day = floor( 20.8431 + 0.242194 * ( $year - 1980 ) - floor( ( $year - 1980 ) / 4 ) );
			if ( $dt->format('j') == $day )
			{
				return $list[0]->title;
			}
		}

		return false;
	}


	// 秋分の日チェック
	public static function check_autumn_holiday($dt = null)
	{
		$dt  = new \DateTime($dt);

		$param = array(
			'where'  => array(
				array('type', '=', self::TYPE_AUTUMN),
				array('date_range1', '<=', $dt->format('Y-m-d')),
				array('date_range2', '>=', $dt->format('Y-m-d')),
				array('month', '=', $dt->format('n')),
			)
		);
		$list = self::find($param);
		if ( $list )
		{
			$year = $dt->format('Y');
			$day = floor( 23.2488 + 0.242194 * ( $year - 1980 ) - floor( ( $year - 1980 ) / 4 ) );
			if ( $dt->format('j') == $day )
			{
				return $list[0]->title;
			}
		}

		return false;
	}


	// 設定された休日チェック
	public static function check_master_holiday($dt = null, $unique = true)
	{
		// 固定日・ハッピーマンデー・春分の日・秋分の日をチェック
		$check = array(
			self::TYPE_FIXED,
			self::TYPE_HAPPY,
			self::TYPE_SPRING,
			self::TYPE_AUTUMN,
		);
		// 創立記念日等の独自休暇もチェックするか否か
		if ( $unique )
		{
			array_unshift($check, self::TYPE_UNIQUE);
			array_unshift($check, self::TYPE_RANGE);
		}

		$result = false;
		foreach ( $check as $type )
		{
			$method = 'check_' . $type . '_holiday';
			$holiday = self::$method($dt);
			if ( $holiday != false )
			{
				$result = $holiday;
				break;
			}
		}
		return $result;
	}


	// 振替休日チェック
	public static function check_trans_holiday($dt = null)
	{
		// 施行日チェック
		$check = new \DateTime('1973-04-12');
		$dt  = new \DateTime($dt);
		if ( $dt < $check ) return false;

		$dt->modify('-1 day');
		if ( $dt->format('w') == 0 && self::check_master_holiday($dt->format('Y-m-d'), false) )
		{
			return '振替休日';
		}
		return false;
	}


	// 祝日の間にはさまれた日は国民の休日チェック
	public static function check_national_holiday($dt = null)
	{
		// 施行日チェック
		$check1 = new \DateTime('2003-01-01');
		$check2 = new \DateTime($dt);
		if ( $check2 < $check1 ) return false;

		$dt1 = new \DateTime($dt);
		$dt1->modify('-1 day');
		$dt2 = new \DateTime($dt);
		$dt2->modify('+1 day');

		if ( self::check_master_holiday($dt1->format('Y-m-d'), false) && self::check_master_holiday($dt2->format('Y-m-d'), false) )
		{
			return '国民の休日';
		}
		return false;
	}


	// 指定日が祝祭日・休日かチェック
	public static function check_holiday($dt = null, $unique = true)
	{
		// 設定された休日チェック
		$result = self::check_master_holiday($dt, $unique);
		if ( $result !== false ) return $result;

		// 振替休日チェック
		$result = self::check_trans_holiday($dt);
		if ( $result !== false ) return $result;

		// 国民の休日チェック
		$result = self::check_national_holiday($dt);
		if ( $result !== false ) return $result;

		return false;
	}


	// 指定範囲で休日リストを取得
	public static function get_list($start_dt = null, $end_dt = null, $unique = true)
	{
		$results = array();

		$dt1 = new \DateTime($start_dt);
		$dt2 = new \DateTime($end_dt);

		$check_dt = new \DateTime($start_dt);
		while ( $check_dt <= $dt2 )
		{
			$holiday = self::check_holiday($check_dt->format('Y-m-d'), $unique);
			if ( $holiday !== false )
			{
				$results[$check_dt->format('Y-m-d')] = $holiday;
			}

			$check_dt->modify('+1 day');
		}

		return $results;
	}


	// 取得時のdel_flgチェック
	protected static function pre_find(&$query)
	{
		// 削除フラグ
		$query->where(self::$_table_name.'.del_flg', 0);
	}

}

?>

FuelPHPのチェッククラス

DB登録画面は省略...


<?php

# 指定日が休日かチェック(日本の祝祭日のみをチェックしたい場合は第ニ引数にfalseをセット)
if ( Model_Holiday_Master::check_holiday('日付') )
{
	// 休日だった場合の処理...
}
else
{
	// 休日でなかった場合の処理...
}

?>

FuelPHPの年間休日の取得の仕方


<?php

# 指定範囲内の休日リストを取得(日本の祝祭日のみを取得したい場合は第三引数にfalseをセット)
$list = Model_Holiday_Master::get_list('開始日', '終了日');

?>

ご参考までに。。。


(・囚・)ノ

INDEXブログ一覧へ
CONTACTお問い合わせはこちら