├── .gitignore ├── composer.json ├── phpunit.xml ├── LICENSE ├── README.md └── src └── Carbon.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor 3 | composer.lock 4 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "citco/carbon", 3 | "description": "This is a wrapper for nesbot/carbon which also calculates which days are British bank holidays (England & Wales only).", 4 | "keywords": ["british","england","wales","bank","holiday","holidays"], 5 | "license": "MIT", 6 | "require": { 7 | "php": "^8.1", 8 | "nesbot/carbon": "3.*" 9 | }, 10 | "autoload": { 11 | "psr-4": { 12 | "Citco\\": "src/" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Creative Investment Technologies 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Carbon with support of UK Bank Holidays 2 | This is a wrapper for [Carbon](https://github.com/briannesbitt/Carbon) which also calculates which days are British bank holidays (England & Wales only). 3 | 4 | 5 | ## Installation 6 | 7 | 8 | ### With Composer 9 | 10 | ``` 11 | $ composer require citco/carbon 12 | ``` 13 | 14 | ```json 15 | { 16 | "require": { 17 | "citco/carbon": "*" 18 | } 19 | } 20 | ``` 21 | 22 | ```php 23 | isBankHoliday() ?: "not bank holiday"; 29 | ``` 30 | 31 | 32 | ### Without Composer 33 | 34 | Why are you not using [composer](http://getcomposer.org/)? Download [Carbon.php](https://github.com/citco/carbon/blob/master/src/Carbon.php) from the repo and save the file into your project path somewhere. (You also need to download [nesbot/carbon](https://github.com/briannesbitt/Carbon)) 35 | 36 | ```php 37 | isBankHoliday() ?: "not bank holiday"; 44 | ``` 45 | 46 | 47 | ### Sample code 48 | 49 | Here are some samples on using this class: 50 | ```php 51 | // Creates a new instance of the class 52 | $c = new Carbon(); // Today's date 53 | $c = new Carbon('2012-05-21'); // Date as string 54 | $c = Carbon::parse('First day of May 2011'); 55 | 56 | // Checks if the given date is bank holiday 57 | $boolean = $c->isBankHoliday('2016-05-21'); 58 | $boolean = $c->isBankHoliday(Carbon::parse('First day of 2000')); 59 | 60 | // Returns array of holidays for the given year 61 | $c->getBankHolidays(2015); 62 | $c->getBankHolidays(array(2010, 2012)); 63 | $c->getBankHolidays(Carbon::now()); 64 | 65 | // Returns New Year date of the given year 66 | $c->getNewYearBankHoliday(2012); // 2012-01-02 67 | 68 | // Without any parameter will return date for the init year 69 | $c->getNewYearBankHoliday(); 70 | $c->getGoodFridayBankHoliday(); 71 | $c->getEasterMondayBankHoliday(); 72 | $c->getEarlyMayBankHoliday(); 73 | $c->getSpringBankHoliday(); 74 | $c->getSummerBankHoliday(); 75 | $c->getBoxingDayBankHoliday(); 76 | $c->getChristmasBankHoliday(); 77 | 78 | // Returns next/previous bank holiday 79 | $c->nextBankHoliday(); 80 | $c->previousBankHoliday(); 81 | 82 | $c->nextBankHoliday(Carbon::parse('Next year May 1st')); 83 | $c->previousBankHoliday(Carbon::parse('Next year May 1st')); 84 | 85 | // Returns N next/previous bank holidays 86 | $n = 20; 87 | $c->nextBankHolidays($n); 88 | $c->previousBankHolidays($n); 89 | 90 | $c->nextBankHolidays($n, Carbon::parse('Next year May 1st')); 91 | $c->previousBankHolidays($n, Carbon::parse('Next year May 1st')); 92 | 93 | // Returns the list of bank holidays between two dates 94 | $start = Carbon::now(); 95 | $end = Carbon::now()->subYear(1); 96 | $holidays = $start->bankHolidaysSince($end); 97 | ``` 98 | 99 | 100 | ### Issues 101 | Bug reports and feature requests can be submitted on the [Github Issue Tracker](https://github.com/citco/carbon/issues). 102 | 103 | 104 | ### Requirements 105 | 106 | PHP 8.1 or above (For older PHP versions, please use the version 1.x or 2.x of this package) 107 | 108 | 109 | ### License 110 | 111 | Bank Holidays is licensed under the MIT License - see the LICENSE file for details 112 | -------------------------------------------------------------------------------- /src/Carbon.php: -------------------------------------------------------------------------------- 1 | 4 ? $date : "{$date}-01-01"); 10 | } 11 | else 12 | { 13 | return $date instanceof \Carbon\Carbon ? $date : $this; 14 | } 15 | } 16 | 17 | public function getNewYearBankHoliday($date = null) 18 | { 19 | $date = $this->getDate($date); 20 | 21 | $day_of_week = (new static)->parse("{$date->year}-01-01")->dayOfWeek; 22 | 23 | $new_year_bank_holiday = "{$date->year}-01-01"; 24 | $day_of_week == 0 AND $new_year_bank_holiday = "{$date->year}-01-02"; 25 | $day_of_week == 6 AND $new_year_bank_holiday = "{$date->year}-01-03"; 26 | 27 | return $new_year_bank_holiday; 28 | } 29 | 30 | public function getGoodFridayBankHoliday($date = null) 31 | { 32 | $date = $this->getDate($date); 33 | 34 | $good_friday_bank_holiday = (new static)->parse("{$date->year}-03-21")->addDays(easter_days($date->year) - 2)->toDateString(); 35 | 36 | return $good_friday_bank_holiday; 37 | } 38 | 39 | public function getEasterMondayBankHoliday($date = null) 40 | { 41 | $date = $this->getDate($date); 42 | 43 | $easter_monday_bank_holiday = (new static)->parse("{$date->year}-03-21")->addDays(easter_days($date->year) + 1)->toDateString(); 44 | 45 | return $easter_monday_bank_holiday; 46 | } 47 | 48 | public function getEarlyMayBankHoliday($date = null) 49 | { 50 | $date = $this->getDate($date); 51 | 52 | if (in_array($date->year, [1995, 2020])) 53 | { 54 | // Victory in Europe day 55 | return "{$date->year}-05-08"; 56 | } 57 | 58 | $day_of_week = (new static)->parse("{$date->year}-05-01")->dayOfWeek; 59 | 60 | $day_of_week == 0 AND $early_may_bank_holiday = "{$date->year}-05-02"; 61 | $day_of_week == 1 AND $early_may_bank_holiday = "{$date->year}-05-01"; 62 | $day_of_week == 2 AND $early_may_bank_holiday = "{$date->year}-05-07"; 63 | $day_of_week == 3 AND $early_may_bank_holiday = "{$date->year}-05-06"; 64 | $day_of_week == 4 AND $early_may_bank_holiday = "{$date->year}-05-05"; 65 | $day_of_week == 5 AND $early_may_bank_holiday = "{$date->year}-05-04"; 66 | $day_of_week == 6 AND $early_may_bank_holiday = "{$date->year}-05-03"; 67 | 68 | return $early_may_bank_holiday; 69 | } 70 | 71 | public function getSpringBankHoliday($date = null) 72 | { 73 | $date = $this->getDate($date); 74 | 75 | if ($date->year == 2002) 76 | { 77 | // Moved for Golden Jubilee of Elizabeth II 78 | return '2002-06-04'; 79 | } 80 | 81 | if ($date->year == 2012) 82 | { 83 | // Moved for Diamond Jubilee of Elizabeth II 84 | return '2012-06-04'; 85 | } 86 | 87 | if ($date->year == 2022) 88 | { 89 | // Moved for Platinum Jubilee of Elizabeth II 90 | return '2022-06-02'; 91 | } 92 | 93 | $day_of_week = (new static)->parse("{$date->year}-05-31")->dayOfWeek; 94 | 95 | $day_of_week == 0 AND $spring_bank_holiday = "{$date->year}-05-25"; 96 | $day_of_week == 1 AND $spring_bank_holiday = "{$date->year}-05-31"; 97 | $day_of_week == 2 AND $spring_bank_holiday = "{$date->year}-05-30"; 98 | $day_of_week == 3 AND $spring_bank_holiday = "{$date->year}-05-29"; 99 | $day_of_week == 4 AND $spring_bank_holiday = "{$date->year}-05-28"; 100 | $day_of_week == 5 AND $spring_bank_holiday = "{$date->year}-05-27"; 101 | $day_of_week == 6 AND $spring_bank_holiday = "{$date->year}-05-26"; 102 | 103 | return $spring_bank_holiday; 104 | } 105 | 106 | public function getSummerBankHoliday($date = null) 107 | { 108 | $date = $this->getDate($date); 109 | 110 | $day_of_week = (new static)->parse("{$date->year}-08-31")->dayOfWeek; 111 | 112 | $day_of_week == 0 AND $summer_bank_holiday = "{$date->year}-08-25"; 113 | $day_of_week == 1 AND $summer_bank_holiday = "{$date->year}-08-31"; 114 | $day_of_week == 2 AND $summer_bank_holiday = "{$date->year}-08-30"; 115 | $day_of_week == 3 AND $summer_bank_holiday = "{$date->year}-08-29"; 116 | $day_of_week == 4 AND $summer_bank_holiday = "{$date->year}-08-28"; 117 | $day_of_week == 5 AND $summer_bank_holiday = "{$date->year}-08-27"; 118 | $day_of_week == 6 AND $summer_bank_holiday = "{$date->year}-08-26"; 119 | 120 | return $summer_bank_holiday; 121 | } 122 | 123 | public function getChristmasBankHoliday($date = null) 124 | { 125 | $date = $this->getDate($date); 126 | 127 | $day_of_week = (new static)->parse("{$date->year}-12-25")->dayOfWeek; 128 | 129 | $christmas_bank_holiday = "{$date->year}-12-25"; 130 | $day_of_week == 0 AND $christmas_bank_holiday = "{$date->year}-12-27"; 131 | $day_of_week == 5 AND $christmas_bank_holiday = "{$date->year}-12-25"; 132 | $day_of_week == 6 AND $christmas_bank_holiday = "{$date->year}-12-27"; 133 | 134 | return $christmas_bank_holiday; 135 | } 136 | 137 | public function getBoxingDayBankHoliday($date = null) 138 | { 139 | $date = $this->getDate($date); 140 | 141 | $day_of_week = (new static)->parse("{$date->year}-12-25")->dayOfWeek; 142 | 143 | $boxing_day_bank_holiday = "{$date->year}-12-26"; 144 | $day_of_week == 0 AND $boxing_day_bank_holiday = "{$date->year}-12-26"; 145 | $day_of_week == 5 AND $boxing_day_bank_holiday = "{$date->year}-12-28"; 146 | $day_of_week == 6 AND $boxing_day_bank_holiday = "{$date->year}-12-28"; 147 | 148 | return $boxing_day_bank_holiday; 149 | } 150 | 151 | public function getBankHolidays($dates = null) 152 | { 153 | is_array($dates) OR $dates = [$dates]; 154 | 155 | foreach ($dates as $index => $date) 156 | { 157 | $dates[$index] = $this->getDate($date); 158 | } 159 | 160 | $bank_holidays = []; 161 | 162 | foreach ($dates as $date) 163 | { 164 | $bank_holidays[$this->getNewYearBankHoliday($date)] = 'New Year\'s Day Holiday'; 165 | $bank_holidays[$this->getGoodFridayBankHoliday($date)] = 'Good Friday'; 166 | $bank_holidays[$this->getEasterMondayBankHoliday($date)] = 'Easter Monday'; 167 | $bank_holidays[$this->getEarlyMayBankHoliday($date)] = 'Early May Bank Holiday'; 168 | $bank_holidays[$this->getSpringBankHoliday($date)] = 'Spring Bank Holiday'; 169 | $bank_holidays[$this->getSummerBankHoliday($date)] = 'Summer Bank Holiday'; 170 | $bank_holidays[$this->getChristmasBankHoliday($date)] = 'Christmas Day Holiday'; 171 | $bank_holidays[$this->getBoxingDayBankHoliday($date)] = 'Boxing Day'; 172 | 173 | $date->year == 1999 AND $bank_holidays['1999-12-31'] = 'Millennium Eve'; 174 | $date->year == 2002 AND $bank_holidays['2002-06-03'] = 'Golden Jubilee Holiday'; 175 | $date->year == 2011 AND $bank_holidays['2011-04-29'] = 'Royal Wedding Bank Holiday'; 176 | $date->year == 2012 AND $bank_holidays['2012-06-05'] = 'Diamond Jubilee Holiday'; 177 | $date->year == 2022 AND $bank_holidays['2022-06-03'] = 'Platinum Jubilee Holiday'; 178 | $date->year == 2022 AND $bank_holidays['2022-09-19'] = 'State Funeral of Queen Elizabeth II'; 179 | $date->year == 2023 AND $bank_holidays['2023-05-08'] = 'Coronation of King Charles III'; 180 | } 181 | 182 | ksort($bank_holidays); 183 | 184 | return $bank_holidays; 185 | } 186 | 187 | public function isBankHoliday($date = null) 188 | { 189 | $date = $this->getDate($date); 190 | 191 | $bank_holidays = $this->getBankHolidays($date); 192 | 193 | if (in_array($date->toDateString(), array_keys($bank_holidays))) 194 | { 195 | return $bank_holidays[$date->toDateString()]; 196 | } 197 | 198 | return false; 199 | } 200 | 201 | public function nextBankHoliday($date = null) 202 | { 203 | return $this->nextBankHolidays(1, $date); 204 | } 205 | 206 | public function previousBankHoliday($date = null) 207 | { 208 | return $this->previousBankHolidays(1, $date); 209 | } 210 | 211 | public function nextBankHolidays($count = 1, $date = null) 212 | { 213 | $date = $this->getDate($date); 214 | 215 | $next_bank_holidays = []; 216 | 217 | $year = static::parse("First day of January {$date->year}"); 218 | 219 | $bank_holidays = $this->getBankHolidays($year); 220 | 221 | while (count($next_bank_holidays) < $count) 222 | { 223 | foreach ($bank_holidays as $bank_holiday => $description) 224 | { 225 | if ($date->lt(static::parse($bank_holiday))) 226 | { 227 | if (count($next_bank_holidays) < $count) 228 | { 229 | $next_bank_holidays[$bank_holiday] = $description; 230 | } 231 | } 232 | } 233 | 234 | $bank_holidays = $this->getBankHolidays($year->addYear()); 235 | } 236 | 237 | ksort($next_bank_holidays); 238 | 239 | return $next_bank_holidays; 240 | } 241 | 242 | public function previousBankHolidays($count = 1, $date = null) 243 | { 244 | $date = $this->getDate($date); 245 | 246 | $previous_bank_holidays = []; 247 | 248 | $year = static::parse("First day of January {$date->year}"); 249 | 250 | $bank_holidays = array_reverse($this->getBankHolidays($year)); 251 | 252 | while (count($previous_bank_holidays) < $count) 253 | { 254 | foreach ($bank_holidays as $bank_holiday => $description) 255 | { 256 | if ($date->gt(static::parse($bank_holiday))) 257 | { 258 | if (count($previous_bank_holidays) < $count) 259 | { 260 | $previous_bank_holidays[$bank_holiday] = $description; 261 | } 262 | } 263 | } 264 | 265 | $bank_holidays = array_reverse($this->getBankHolidays($year->subYear())); 266 | } 267 | 268 | ksort($previous_bank_holidays); 269 | 270 | return $previous_bank_holidays; 271 | } 272 | 273 | public function bankHolidaysSince($date) 274 | { 275 | $start = $this->getDate($date); 276 | $end = $this; 277 | 278 | if ($end->lt($start)) 279 | { 280 | $temp = $end; 281 | $end = $start; 282 | $start = $temp; 283 | } 284 | 285 | $years = []; 286 | 287 | for ($i = $start->year; $i <= $end->year; $i++) 288 | { 289 | $years[] = $i; 290 | } 291 | 292 | $holidays = $this->getBankHolidays($years); 293 | 294 | foreach ($holidays as $date => $holiday) 295 | { 296 | if (! (new static($date))->between($start, $end)) 297 | { 298 | unset($holidays[$date]); 299 | } 300 | } 301 | 302 | return $holidays; 303 | } 304 | } 305 | --------------------------------------------------------------------------------