LoginSignup
9
10

More than 5 years have passed since last update.

n日後の営業日を取得する

Last updated at Posted at 2015-10-16

祝日・振替休日を取得するには 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
9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10