├── README.md ├── LICENSE └── HolidayDateTime.php /README.md: -------------------------------------------------------------------------------- 1 | # HolidayDateTime 2 | A php class to check Japanese holiday and weekend. 土日祝日を判定するphpクラス。 3 | 4 | ## Usage 5 | 6 | ``` 7 | $date = new HolidayDateTime("2017-05-28"); 8 | $date->holiday();//"日" 9 | ``` 10 | 11 | It will return false if the date is not a holiday or weekend and return the name of holiday or weekend if it is. 12 | 13 | ## Referenced 14 | [祝日を自動判定するDateTime拡張クラス](http://qiita.com/chiyoyo/items/539dc2840a1b70a8e2c3) 15 | 16 | [DateTime クラスのまとめメモ](http://qiita.com/re-24/items/c3ed814f2e1ee0f8e811) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ziyang Liao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /HolidayDateTime.php: -------------------------------------------------------------------------------- 1 | holiday(); 5 | */ 6 | class HolidayDateTime extends DateTime 7 | { 8 | /** 祝日一覧 */ 9 | // 種別: 10 | // fixed=日付固定 11 | // happy=指定の週の月曜日 12 | // spring=春分の日専用 13 | // autumn=秋分の日専用 14 | private static $holidays = [ 15 | // 種別, 月, 日or週, 開始年, 終了年, 祝日名 16 | ['fixed', 1, 1, 1949, 9999, '元日'], 17 | ['fixed', 1, 15, 1949, 1999, '成人の日'], 18 | ['happy', 1, 2, 2000, 9999, '成人の日'], 19 | ['fixed', 2, 11, 1967, 9999, '建国記念の日'], 20 | ['spring', 3, 0, 1949, 9999, '春分の日'], 21 | ['fixed', 4, 29, 1949, 1989, '天皇誕生日'], 22 | ['fixed', 4, 29, 1990, 2006, 'みどりの日'], 23 | ['fixed', 4, 29, 2007, 9999, '昭和の日'], 24 | ['fixed', 5, 3, 1949, 9999, '憲法記念日'], 25 | ['fixed', 5, 4, 1988, 2006, '国民の休日'], 26 | ['fixed', 5, 4, 2007, 9999, 'みどりの日'], 27 | ['fixed', 5, 5, 1949, 9999, 'こどもの日'], 28 | ['happy', 7, 3, 2003, 9999, '海の日'], 29 | ['fixed', 7, 20, 1996, 2002, '海の日'], 30 | ['fixed', 8, 11, 2016, 9999, '山の日'], 31 | ['autumn', 9, 0, 1948, 9999, '秋分の日'], 32 | ['fixed', 9, 15, 1966, 2002, '敬老の日'], 33 | ['happy', 9, 3, 2003, 9999, '敬老の日'], 34 | ['fixed', 10, 10, 1966, 1999, '体育の日'], 35 | ['happy', 10, 2, 2000, 9999, '体育の日'], 36 | ['fixed', 11, 3, 1948, 9999, '文化の日'], 37 | ['fixed', 11, 23, 1948, 9999, '勤労感謝の日'], 38 | ['fixed', 12, 23, 1989, 9999, '天皇誕生日'], 39 | //以下、1年だけの祝日 40 | ['fixed', 4, 10, 1959, 1959, '皇太子明仁親王の結婚の儀'], 41 | ['fixed', 2, 24, 1989, 1989, '昭和天皇の大喪の礼'], 42 | ['fixed', 11, 12, 1990, 1990, '即位礼正殿の儀'], 43 | ['fixed', 6, 9, 1993, 1993, '皇太子徳仁親王の結婚の儀'], 44 | ]; 45 | 46 | /** 47 | * 祝日を取得 48 | */ 49 | public function holiday() 50 | { 51 | // 設定された休日チェック 52 | $result = $this->checkHoliday(); 53 | if ($result !== false) return $result; 54 | 55 | // 振替休日チェック 56 | $result = $this->checkTransferHoliday(); 57 | if ($result !== false) return $result; 58 | 59 | // 土日チェック 60 | $result = $this->checkWeekend(); 61 | if ($result !== false) return $result; 62 | 63 | // 国民の休日チェック 64 | $result = $this->checkNationalHoliday(); 65 | 66 | return $result; 67 | } 68 | 69 | /** 70 | * 設定された休日のみチェック 71 | * 国民の休日と振替休日はチェックしない 72 | */ 73 | public function checkHoliday() 74 | { 75 | $result = false; 76 | 77 | // 全ての祝日を判定 78 | foreach(self::$holidays as $holiday) { 79 | list($method, $month, $day, $start, $end, $name) = $holiday; 80 | $method .= 'Holiday'; 81 | $result = $this->$method($month, $day, $start, $end, $name); 82 | if ($result) { 83 | return $result; 84 | } 85 | } 86 | return $result; 87 | } 88 | 89 | /** 90 | * 振替休日チェック 91 | */ 92 | public function checkTransferHoliday() 93 | { 94 | // 施行日チェック 95 | $d = new DateTime('1973-04-12'); 96 | if ($this < $d) return false; 97 | 98 | // 当日が祝日の場合はfalse 99 | if ($this->checkHoliday()) return false; 100 | 101 | $num = ($this->year <= 2006) ? 1 : 7; //改正法なら最大7日間遡る 102 | 103 | $d = clone $this; 104 | $d->modify('-1 day'); 105 | $isTransfer = false; 106 | for ($i = 0 ; $i < $num ; $i++) { 107 | if ($d->checkHoliday()) { 108 | // 祝日かつ日曜ならば振替休日 109 | if ($d->dayOfWeek == 0) { 110 | $isTransfer = true; 111 | break; 112 | } 113 | $d->modify('-1 day'); 114 | } else { 115 | break; 116 | } 117 | } 118 | return $isTransfer ? '振替休日' : false; 119 | } 120 | 121 | /** 122 | * 国民の休日かどうかチェック 123 | */ 124 | public function checkNationalHoliday() 125 | { 126 | // 施行日チェック 127 | $d = new DateTime('2003-01-01'); 128 | if ($this < $d) return false; 129 | 130 | $before = clone $this; 131 | $before->modify('-1 day'); 132 | if ($before->checkHoliday() === false) return false; 133 | 134 | $after = clone $this; 135 | $after->modify('+1 day'); 136 | if ($after->checkHoliday() === false) return false; 137 | 138 | return '国民の休日'; 139 | } 140 | 141 | /** 142 | * 土日かどうかチェック 143 | */ 144 | public function checkWeekend(){ 145 | $weekday = array("日","月","火","水","木","金","土"); 146 | $w = $this->format('w'); 147 | if($w == 0 || $w == 6){ 148 | return $weekday[$w]; 149 | } 150 | else{ 151 | return false; 152 | } 153 | } 154 | 155 | /** 156 | * 固定祝日かどうか 157 | */ 158 | private function fixedHoliday($month, $day, $start, $end, $name) 159 | { 160 | if ($this->isWithinYear($start, $end) === false) return false; 161 | if ($this->month != $month) return false; 162 | 163 | if ($this->day != $day) return false; 164 | return $name; 165 | } 166 | 167 | /** 168 | * ハッピーマンデー 169 | */ 170 | private function happyHoliday($month, $week, $start, $end, $name) 171 | { 172 | if ($this->isWithinYear($start, $end) === false) return false; 173 | if ($this->month != $month) return false; 174 | 175 | // 第*月曜日の日付を求める 176 | $w = 1; // 月曜日固定 177 | $d1 = new HolidayDateTime($this->format('Y-m-1')); 178 | $w1 = intval($d1->dayOfWeek); 179 | $day = $w - $w1 < 0 ? 7 + $w - $w1 : $w - $w1; 180 | $day++; 181 | $day = $day + 7 * ($week - 1); 182 | 183 | if ($this->day != $day) return false; 184 | return $name; 185 | } 186 | 187 | /** 188 | * 春分の日 189 | */ 190 | private function springHoliday($month, $dummy, $start, $end, $name) 191 | { 192 | if ($this->isWithinYear($start, $end) === false) return false; 193 | if ($this->month != $month) return false; 194 | 195 | $year = $this->year; 196 | $day = floor(20.8431 + 0.242194 * ($year - 1980) - floor(($year - 1980) / 4)); 197 | 198 | if ($this->day != $day) return false; 199 | return $name; 200 | } 201 | 202 | /** 203 | * 秋分の日 204 | */ 205 | private function autumnHoliday($month, $dummy, $start, $end, $name) 206 | { 207 | if ($this->isWithinYear($start, $end) === false) return false; 208 | if ($this->month != $month) return false; 209 | 210 | $year = $this->year; 211 | $day = floor(23.2488 + 0.242194 * ($year - 1980) - floor(($year - 1980) / 4)); 212 | 213 | if ($this->day != $day) return false; 214 | return $name; 215 | } 216 | 217 | /** 218 | * 年が祝日適用範囲内であるか 219 | */ 220 | private function isWithinYear($start, $end) 221 | { 222 | if ($this->year < $start || $end < $this->year) { 223 | return false; 224 | } 225 | return true; 226 | } 227 | 228 | // 以下Carbonを継承している場合は削除すべし 229 | public function __get($name) 230 | { 231 | switch (true) { 232 | case array_key_exists($name, $formats = [ 233 | 'year' => 'Y', 234 | 'month' => 'n', 235 | 'day' => 'j', 236 | 'hour' => 'G', 237 | 'minute' => 'i', 238 | 'second' => 's', 239 | 'micro' => 'u', 240 | 'dayOfWeek' => 'w', 241 | 'dayOfYear' => 'z', 242 | 'weekOfYear' => 'W', 243 | 'daysInMonth' => 't', 244 | 'timestamp' => 'U', 245 | ]): 246 | return (int) $this->format($formats[$name]); 247 | } 248 | } 249 | } 250 | 251 | --------------------------------------------------------------------------------