|
1
|
|
|
<?php declare(strict_types=1); |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* This file is part of the Yasumi package. |
|
5
|
|
|
* |
|
6
|
|
|
* Copyright (c) 2015 - 2020 AzuyaLabs |
|
7
|
|
|
* |
|
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
9
|
|
|
* file that was distributed with this source code. |
|
10
|
|
|
* |
|
11
|
|
|
* @author Sacha Telgenhof <[email protected]> |
|
12
|
|
|
*/ |
|
13
|
|
|
|
|
14
|
|
|
namespace Yasumi\Provider; |
|
15
|
|
|
|
|
16
|
|
|
use DateInterval; |
|
17
|
|
|
use DateTime; |
|
18
|
|
|
use Yasumi\Exception\InvalidDateException; |
|
19
|
|
|
use Yasumi\Exception\UnknownLocaleException; |
|
20
|
|
|
use Yasumi\Holiday; |
|
21
|
|
|
use Yasumi\SubstituteHoliday; |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* Provider for all holidays in the South Korea except for election day and temporary public holiday. |
|
25
|
|
|
* |
|
26
|
|
|
* @link https://en.wikipedia.org/wiki/Public_holidays_in_South_Korea |
|
27
|
|
|
*/ |
|
28
|
|
|
class SouthKorea extends AbstractProvider |
|
29
|
|
|
{ |
|
30
|
|
|
use CommonHolidays, ChristianHolidays; |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* Code to identify this Holiday Provider. Typically this is the ISO3166 code corresponding to the respective |
|
34
|
|
|
* country or sub-region. |
|
35
|
|
|
*/ |
|
36
|
|
|
public const ID = 'KR'; |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* Dates in Gregorian calendar of Seollal, Buddha's Birthday, and Chuseok (~ 2050) |
|
40
|
|
|
* |
|
41
|
|
|
* The Korean calendar is derived from the Chinese calendar. Although not being an official calendar, the |
|
42
|
|
|
* traditional Korean calendar is still maintained by the government. The current version is based on China's |
|
43
|
|
|
* Shixian calendar, which was in turn developed by Jesuit scholars. However, because the Korean calendar is now |
|
44
|
|
|
* based on the moon's shape seen from Korea, occasionally the calendar diverges from the traditional Chinese |
|
45
|
|
|
* calendar by one day, even though the underlying rule is the same. |
|
46
|
|
|
* @link https://en.wikipedia.org/wiki/Korean_calendar |
|
47
|
|
|
* |
|
48
|
|
|
* To convert from lunar calendar to Gregorian calendar, lunar observation is necessary. |
|
49
|
|
|
* There is no perfect formula, and as it moves away from the current date, the error becomes bigger. |
|
50
|
|
|
* Korea Astronomy and Space Science Institute (KASI) is supporting the converter until 2050. |
|
51
|
|
|
* For more information, please refer to the paper below. |
|
52
|
|
|
* 박(2017)총,32(3),407-420. |
|
53
|
|
|
* @link https://www.kasi.re.kr/kor/research/paper/20170259 - Korea Astronomy and Space Science Institute |
|
54
|
|
|
*/ |
|
55
|
|
|
public const LUNAR_HOLIDAY = [ |
|
56
|
|
|
'seollal' => [ |
|
57
|
|
|
1985 => '1985-2-20', 1986 => '1986-2-9', 1987 => '1987-1-29', 1988 => '1988-2-18', 1989 => '1989-2-6', |
|
58
|
|
|
1990 => '1990-1-27', 1991 => '1991-2-15', 1992 => '1992-2-4', 1993 => '1993-1-23', 1994 => '1994-2-10', |
|
59
|
|
|
1995 => '1995-1-31', 1996 => '1996-2-19', 1997 => '1997-2-8', 1998 => '1998-1-28', 1999 => '1999-2-16', |
|
60
|
|
|
2000 => '2000-2-5', 2001 => '2001-1-24', 2002 => '2002-2-12', 2003 => '2003-2-1', 2004 => '2004-1-22', |
|
61
|
|
|
2005 => '2005-2-9', 2006 => '2006-1-29', 2007 => '2007-2-18', 2008 => '2008-2-7', 2009 => '2009-1-26', |
|
62
|
|
|
2010 => '2010-2-14', 2011 => '2011-2-3', 2012 => '2012-1-23', 2013 => '2013-2-10', 2014 => '2014-1-31', |
|
63
|
|
|
2015 => '2015-2-19', 2016 => '2016-2-8', 2017 => '2017-1-28', 2018 => '2018-2-16', 2019 => '2019-2-5', |
|
64
|
|
|
2020 => '2020-1-25', 2021 => '2021-2-12', 2022 => '2022-2-1', 2023 => '2023-1-22', 2024 => '2024-2-10', |
|
65
|
|
|
2025 => '2025-1-29', 2026 => '2026-2-17', 2027 => '2027-2-7', 2028 => '2028-1-27', 2029 => '2029-2-13', |
|
66
|
|
|
2030 => '2030-2-3', 2031 => '2031-1-23', 2032 => '2032-2-11', 2033 => '2033-1-31', 2034 => '2034-2-19', |
|
67
|
|
|
2035 => '2035-2-8', 2036 => '2036-1-28', 2037 => '2037-2-15', 2038 => '2038-2-4', 2039 => '2037-1-24', |
|
68
|
|
|
2040 => '2040-2-12', 2041 => '2041-2-1', 2042 => '2042-1-22', 2043 => '2043-2-10', 2044 => '2044-1-30', |
|
69
|
|
|
2045 => '2045-2-17', 2046 => '2046-2-6', 2047 => '2047-1-26', 2048 => '2048-2-14', 2049 => '2049-2-2', |
|
70
|
|
|
2050 => '2050-1-23', |
|
71
|
|
|
], |
|
72
|
|
|
'buddhasBirthday' => [ |
|
73
|
|
|
1975 => '1975-5-18', 1976 => '1976-5-6', 1977 => '1977-5-25', 1978 => '1978-5-14', 1979 => '1979-5-3', |
|
74
|
|
|
1980 => '1980-5-21', 1981 => '1981-5-11', 1982 => '1982-5-1', 1983 => '1983-5-20', 1984 => '1984-5-8', |
|
75
|
|
|
1985 => '1985-5-27', 1986 => '1986-5-16', 1987 => '1987-5-5', 1988 => '1988-5-23', 1989 => '1989-5-12', |
|
76
|
|
|
1990 => '1990-5-2', 1991 => '1991-5-21', 1992 => '1992-5-10', 1993 => '1993-5-28', 1994 => '1994-5-18', |
|
77
|
|
|
1995 => '1995-5-7', 1996 => '1996-5-24', 1997 => '1997-5-14', 1998 => '1998-5-3', 1999 => '1999-5-22', |
|
78
|
|
|
2000 => '2000-5-11', 2001 => '2001-4-30', 2002 => '2002-5-19', 2003 => '2003-5-8', 2004 => '2004-5-26', |
|
79
|
|
|
2005 => '2005-5-15', 2006 => '2006-5-5', 2007 => '2007-5-24', 2008 => '2008-5-12', 2009 => '2009-5-2', |
|
80
|
|
|
2010 => '2010-5-21', 2011 => '2011-5-10', 2012 => '2012-5-28', 2013 => '2013-5-17', 2014 => '2014-5-6', |
|
81
|
|
|
2015 => '2015-5-25', 2016 => '2016-5-14', 2017 => '2017-5-3', 2018 => '2018-5-22', 2019 => '2019-5-12', |
|
82
|
|
|
2020 => '2020-4-30', 2021 => '2021-5-19', 2022 => '2022-5-8', 2023 => '2023-5-27', 2024 => '2024-5-15', |
|
83
|
|
|
2025 => '2025-5-5', 2026 => '2026-5-24', 2027 => '2027-5-13', 2028 => '2028-5-2', 2029 => '2029-5-20', |
|
84
|
|
|
2030 => '2030-5-9', 2031 => '2031-5-28', 2032 => '2032-5-16', 2033 => '2033-5-6', 2034 => '2034-5-25', |
|
85
|
|
|
2035 => '2035-5-15', 2036 => '2036-5-3', 2037 => '2037-5-22', 2038 => '2038-5-11', 2039 => '2039-4-30', |
|
86
|
|
|
2040 => '2040-5-18', 2041 => '2041-5-7', 2042 => '2042-5-26', 2043 => '2043-5-16', 2044 => '2044-5-5', |
|
87
|
|
|
2045 => '2045-5-24', 2046 => '2046-5-13', 2047 => '2047-5-2', 2048 => '2048-5-20', 2049 => '2049-5-9', |
|
88
|
|
|
2050 => '2050-5-28', |
|
89
|
|
|
], |
|
90
|
|
|
'chuseok' => [ |
|
91
|
|
|
1949 => '1949-10-6', 1950 => '1950-9-26', 1951 => '1951-9-15', 1952 => '1952-10-3', 1953 => '1953-9-22', |
|
92
|
|
|
1954 => '1954-9-11', 1955 => '1955-9-30', 1956 => '1956-9-19', 1957 => '1957-9-8', 1958 => '1958-9-27', |
|
93
|
|
|
1959 => '1959-9-17', 1960 => '1960-10-5', 1961 => '1961-9-24', 1962 => '1962-9-13', 1963 => '1963-10-2', |
|
94
|
|
|
1964 => '1964-9-20', 1965 => '1965-9-10', 1966 => '1966-9-29', 1967 => '1967-9-18', 1968 => '1968-10-6', |
|
95
|
|
|
1969 => '1969-9-26', 1970 => '1970-9-15', 1971 => '1971-10-3', 1972 => '1972-9-22', 1973 => '1973-9-11', |
|
96
|
|
|
1974 => '1974-9-30', 1975 => '1975-9-20', 1976 => '1976-9-8', 1977 => '1977-9-27', 1978 => '1978-9-17', |
|
97
|
|
|
1979 => '1979-10-5', 1980 => '1980-9-23', 1981 => '1981-9-12', 1982 => '1982-10-1', 1983 => '1983-9-21', |
|
98
|
|
|
1984 => '1984-9-10', 1985 => '1985-9-29', 1986 => '1986-9-18', 1987 => '1987-10-7', 1988 => '1988-9-25', |
|
99
|
|
|
1989 => '1989-9-14', 1990 => '1990-10-3', 1991 => '1991-9-22', 1992 => '1992-9-11', 1993 => '1993-9-30', |
|
100
|
|
|
1994 => '1994-9-20', 1995 => '1950-9-9', 1996 => '1996-9-27', 1997 => '1997-9-16', 1998 => '1998-10-5', |
|
101
|
|
|
1999 => '1999-9-24', 2000 => '2000-9-12', 2001 => '2001-10-1', 2002 => '2002-9-21', 2003 => '2003-9-11', |
|
102
|
|
|
2004 => '2004-9-28', 2005 => '2005-9-18', 2006 => '2006-10-6', 2007 => '2007-9-25', 2008 => '2008-9-14', |
|
103
|
|
|
2009 => '2009-10-3', 2010 => '2010-9-22', 2011 => '2011-9-12', 2012 => '2012-9-30', 2013 => '2013-9-19', |
|
104
|
|
|
2014 => '2014-9-8', 2015 => '2015-9-27', 2016 => '2016-9-15', 2017 => '2017-10-4', 2018 => '2018-9-24', |
|
105
|
|
|
2019 => '2019-9-13', 2020 => '2020-10-1', 2021 => '2021-9-21', 2022 => '2022-9-10', 2023 => '2023-9-29', |
|
106
|
|
|
2024 => '2024-9-17', 2025 => '2025-10-6', 2026 => '2026-9-25', 2027 => '2027-9-15', 2028 => '2028-10-3', |
|
107
|
|
|
2029 => '2029-9-22', 2030 => '2030-9-12', 2031 => '2031-10-1', 2032 => '2032-9-19', 2033 => '2033-9-8', |
|
108
|
|
|
2034 => '2034-9-27', 2035 => '2035-9-16', 2036 => '2036-10-4', 2037 => '2037-9-24', 2038 => '2038-9-13', |
|
109
|
|
|
2039 => '2039-10-2', 2040 => '2040-9-21', 2041 => '2041-9-10', 2042 => '2042-9-28', 2043 => '2043-9-17', |
|
110
|
|
|
2044 => '2044-10-5', 2045 => '2045-9-25', 2046 => '2046-9-15', 2047 => '2047-10-4', 2048 => '2048-9-22', |
|
111
|
|
|
2049 => '2049-9-11', 2050 => '2050-9-30', |
|
112
|
|
|
], |
|
113
|
|
|
]; |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* Initialize holidays for South Korea. |
|
117
|
|
|
* |
|
118
|
|
|
* @throws InvalidDateException |
|
119
|
|
|
* @throws \InvalidArgumentException |
|
120
|
|
|
* @throws UnknownLocaleException |
|
121
|
|
|
* @throws \Exception |
|
122
|
|
|
*/ |
|
123
|
|
|
public function initialize(): void |
|
124
|
|
|
{ |
|
125
|
|
|
$this->timezone = 'Asia/Seoul'; |
|
126
|
|
|
|
|
127
|
|
|
// Add common holidays |
|
128
|
|
|
$this->calculateNewYearsDay(); |
|
129
|
|
|
if ($this->year >= 1949) { |
|
130
|
|
|
$this->addHoliday($this->christmasDay($this->year, $this->timezone, $this->locale)); |
|
131
|
|
|
} |
|
132
|
|
|
|
|
133
|
|
|
// Calculate lunar holidays |
|
134
|
|
|
$this->calculateSeollal(); |
|
135
|
|
|
$this->calculateBuddhasBirthday(); |
|
136
|
|
|
$this->calculateChuseok(); |
|
137
|
|
|
|
|
138
|
|
|
// Calculate other holidays |
|
139
|
|
|
$this->calculateIndependenceMovementDay(); |
|
140
|
|
|
$this->calculateArborDay(); |
|
141
|
|
|
$this->calculateChildrensDay(); |
|
142
|
|
|
$this->calculateMemorialDay(); |
|
143
|
|
|
$this->calculateConstitutionDay(); |
|
144
|
|
|
$this->calculateLiberationDay(); |
|
145
|
|
|
$this->calculateArmedForcesDay(); |
|
146
|
|
|
$this->calculateNationalFoundationDay(); |
|
147
|
|
|
$this->calculateHangulDay(); |
|
148
|
|
|
$this->calculateSubstituteHolidays(); |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
/** |
|
152
|
|
|
* New Year's Day. New Year's Day is held on January 1st and established since 1950. |
|
153
|
|
|
* From the enactment of the First Law to 1998, there was a two or three-day break in the New Year. |
|
154
|
|
|
* |
|
155
|
|
|
* @link https://en.wikipedia.org/wiki/New_Year%27s_Day#East_Asian |
|
156
|
|
|
* |
|
157
|
|
|
* @throws \Exception |
|
158
|
|
|
*/ |
|
159
|
|
|
public function calculateNewYearsDay(): void |
|
160
|
|
|
{ |
|
161
|
|
|
if ($this->year >= 1950) { |
|
162
|
|
|
$this->addHoliday($this->newYearsDay($this->year, $this->timezone, $this->locale)); |
|
163
|
|
|
if ($this->year <= 1998) { |
|
164
|
|
|
$this->addHoliday(new Holiday( |
|
165
|
|
|
'dayAfterNewYearsDay', |
|
166
|
|
|
[], |
|
167
|
|
|
new DateTime("$this->year-1-2", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
168
|
|
|
$this->locale |
|
169
|
|
|
)); |
|
170
|
|
|
} |
|
171
|
|
|
if ($this->year <= 1990) { |
|
172
|
|
|
$this->addHoliday(new Holiday( |
|
173
|
|
|
'twoDaysLaterNewYearsDay', |
|
174
|
|
|
['en' => 'Two Days Later New Year’s Day', 'ko' => '새해 연휴'], |
|
175
|
|
|
new DateTime("$this->year-1-3", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
176
|
|
|
$this->locale |
|
177
|
|
|
)); |
|
178
|
|
|
} |
|
179
|
|
|
} |
|
180
|
|
|
} |
|
181
|
|
|
|
|
182
|
|
|
/** |
|
183
|
|
|
* Seollal (Korean New Year's Day). |
|
184
|
|
|
* Seollal is held on the 1st day of the 1st lunar month and was established from 1985. |
|
185
|
|
|
* |
|
186
|
|
|
* @link https://en.wikipedia.org/wiki/Korean_New_Year |
|
187
|
|
|
* |
|
188
|
|
|
* @throws \Exception |
|
189
|
|
|
*/ |
|
190
|
|
|
public function calculateSeollal(): void |
|
191
|
|
|
{ |
|
192
|
|
|
if ($this->year >= 1985 && isset(self::LUNAR_HOLIDAY['seollal'][$this->year])) { |
|
193
|
|
|
$seollal = new DateTime(self::LUNAR_HOLIDAY['seollal'][$this->year], DateTimeZoneFactory::getDateTimeZone($this->timezone)); |
|
194
|
|
|
$this->addHoliday(new Holiday( |
|
195
|
|
|
'seollal', |
|
196
|
|
|
['en' => 'Seollal', 'ko' => '설날'], |
|
197
|
|
|
$seollal, |
|
198
|
|
|
$this->locale |
|
199
|
|
|
)); |
|
200
|
|
|
if ($this->year > 1989) { |
|
201
|
|
|
$dayBeforeSeollal = clone $seollal; |
|
202
|
|
|
$dayBeforeSeollal->sub(new DateInterval('P1D')); |
|
203
|
|
|
$this->addHoliday(new Holiday( |
|
204
|
|
|
'dayBeforeSeollal', |
|
205
|
|
|
['en' => 'Day before Seollal', 'ko' => '설날 연휴'], |
|
206
|
|
|
$dayBeforeSeollal, |
|
207
|
|
|
$this->locale |
|
208
|
|
|
)); |
|
209
|
|
|
$dayAfterSeollal = clone $seollal; |
|
210
|
|
|
$dayAfterSeollal->add(new DateInterval('P1D')); |
|
211
|
|
|
$this->addHoliday(new Holiday( |
|
212
|
|
|
'dayAfterSeollal', |
|
213
|
|
|
['en' => 'Day after Seollal', 'ko' => '설날 연휴'], |
|
214
|
|
|
$dayAfterSeollal, |
|
215
|
|
|
$this->locale |
|
216
|
|
|
)); |
|
217
|
|
|
} |
|
218
|
|
|
} |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
/** |
|
222
|
|
|
* Buddha's Birthday is held on the 8th day of the 4th lunar month and was established since 1975. |
|
223
|
|
|
* |
|
224
|
|
|
* @link https://en.wikipedia.org/wiki/Buddha%27s_Birthday |
|
225
|
|
|
* |
|
226
|
|
|
* @throws \Exception |
|
227
|
|
|
*/ |
|
228
|
|
|
public function calculateBuddhasBirthday(): void |
|
229
|
|
|
{ |
|
230
|
|
|
if ($this->year >= 1975 && isset(self::LUNAR_HOLIDAY['buddhasBirthday'][$this->year])) { |
|
231
|
|
|
$this->addHoliday(new Holiday( |
|
232
|
|
|
'buddhasBirthday', |
|
233
|
|
|
['en' => 'Buddha’s Birthday', 'ko' => '부처님오신날'], |
|
234
|
|
|
new DateTime(self::LUNAR_HOLIDAY['buddhasBirthday'][$this->year], DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
235
|
|
|
$this->locale |
|
236
|
|
|
)); |
|
237
|
|
|
} |
|
238
|
|
|
} |
|
239
|
|
|
|
|
240
|
|
|
/** |
|
241
|
|
|
* Chuseok (Korean Thanksgiving Day). |
|
242
|
|
|
* |
|
243
|
|
|
* Chuseok, one of the biggest holidays in Korea, is a major harvest festival and a three-day holiday celebrated on |
|
244
|
|
|
* the 15th day of the 8th month of the lunar calendar on the full moon. |
|
245
|
|
|
* |
|
246
|
|
|
* @link https://en.wikipedia.org/wiki/Chuseok |
|
247
|
|
|
* |
|
248
|
|
|
* @throws \Exception |
|
249
|
|
|
*/ |
|
250
|
|
|
public function calculateChuseok(): void |
|
251
|
|
|
{ |
|
252
|
|
|
if ($this->year >= 1949 && isset(self::LUNAR_HOLIDAY['chuseok'][$this->year])) { |
|
253
|
|
|
// Chuseok |
|
254
|
|
|
$chuseok = new Holiday( |
|
255
|
|
|
'chuseok', |
|
256
|
|
|
['en' => 'Chuseok', 'ko' => '추석'], |
|
257
|
|
|
new DateTime(self::LUNAR_HOLIDAY['chuseok'][$this->year], DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
258
|
|
|
$this->locale |
|
259
|
|
|
); |
|
260
|
|
|
$this->addHoliday($chuseok); |
|
261
|
|
|
|
|
262
|
|
|
// Day after Chuseok |
|
263
|
|
|
if ($this->year >= 1986) { |
|
264
|
|
|
$this->addHoliday(new Holiday( |
|
265
|
|
|
'dayAfterChuseok', |
|
266
|
|
|
['en' => 'Day after Chuseok', 'ko' => '추석 연휴'], |
|
267
|
|
|
(clone $chuseok)->add(new DateInterval('P1D')), |
|
268
|
|
|
$this->locale |
|
269
|
|
|
)); |
|
270
|
|
|
} |
|
271
|
|
|
|
|
272
|
|
|
// Day before Chuseok |
|
273
|
|
|
if ($this->year >= 1989) { |
|
274
|
|
|
$this->addHoliday(new Holiday( |
|
275
|
|
|
'dayBeforeChuseok', |
|
276
|
|
|
['en' => 'Day before Chuseok', 'ko' => '추석 연휴'], |
|
277
|
|
|
(clone $chuseok)->sub(new DateInterval('P1D')), |
|
278
|
|
|
$this->locale |
|
279
|
|
|
)); |
|
280
|
|
|
} |
|
281
|
|
|
} |
|
282
|
|
|
} |
|
283
|
|
|
|
|
284
|
|
|
/** |
|
285
|
|
|
* Independence Movement Day. Independence Movement Day is held on March 1st and was established from 1949. |
|
286
|
|
|
* |
|
287
|
|
|
* @link https://en.wikipedia.org/wiki/Independence_Movement_Day |
|
288
|
|
|
* |
|
289
|
|
|
* @throws \Exception |
|
290
|
|
|
*/ |
|
291
|
|
|
public function calculateIndependenceMovementDay(): void |
|
292
|
|
|
{ |
|
293
|
|
|
if ($this->year >= 1949) { |
|
294
|
|
|
$this->addHoliday(new Holiday( |
|
295
|
|
|
'independenceMovementDay', |
|
296
|
|
|
['en' => 'Independence Movement Day', 'ko' => '삼일절'], |
|
297
|
|
|
new DateTime("$this->year-3-1", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
298
|
|
|
$this->locale |
|
299
|
|
|
)); |
|
300
|
|
|
} |
|
301
|
|
|
} |
|
302
|
|
|
|
|
303
|
|
|
/** |
|
304
|
|
|
* Sikmogil (Arbor Day). Sikmogil is held on May 5th and established since 1949. |
|
305
|
|
|
* |
|
306
|
|
|
* @link https://en.wikipedia.org/wiki/Sikmogil |
|
307
|
|
|
* |
|
308
|
|
|
* @throws \Exception |
|
309
|
|
|
*/ |
|
310
|
|
|
public function calculateArborDay(): void |
|
311
|
|
|
{ |
|
312
|
|
|
if (($this->year >= 1949 && $this->year < 1960) || ($this->year > 1960 && $this->year < 2006)) { |
|
313
|
|
|
$this->addHoliday(new Holiday( |
|
314
|
|
|
'arborDay', |
|
315
|
|
|
['en' => 'Arbor Day', 'ko' => '식목일'], |
|
316
|
|
|
new DateTime("$this->year-4-5", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
317
|
|
|
$this->locale |
|
318
|
|
|
)); |
|
319
|
|
|
} |
|
320
|
|
|
} |
|
321
|
|
|
|
|
322
|
|
|
/** |
|
323
|
|
|
* Children's Day. Children's Day is held on May 5th and established since 1970. |
|
324
|
|
|
* |
|
325
|
|
|
* @link https://en.wikipedia.org/wiki/Children%27s_Day#South_Korea |
|
326
|
|
|
* |
|
327
|
|
|
* @throws \Exception |
|
328
|
|
|
*/ |
|
329
|
|
|
public function calculateChildrensDay(): void |
|
330
|
|
|
{ |
|
331
|
|
|
if ($this->year >= 1970) { |
|
332
|
|
|
$this->addHoliday(new Holiday( |
|
333
|
|
|
'childrensDay', |
|
334
|
|
|
['en' => 'Children’s Day', 'ko' => '어린이날'], |
|
335
|
|
|
new DateTime("$this->year-5-5", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
336
|
|
|
$this->locale |
|
337
|
|
|
)); |
|
338
|
|
|
} |
|
339
|
|
|
} |
|
340
|
|
|
|
|
341
|
|
|
/** |
|
342
|
|
|
* Memorial Day. Memorial Day is held on June 6th and established since 1956. |
|
343
|
|
|
* |
|
344
|
|
|
* @link https://en.wikipedia.org/wiki/Memorial_Day_(South_Korea) |
|
345
|
|
|
* |
|
346
|
|
|
* @throws \Exception |
|
347
|
|
|
*/ |
|
348
|
|
|
public function calculateMemorialDay(): void |
|
349
|
|
|
{ |
|
350
|
|
|
if ($this->year >= 1966) { |
|
351
|
|
|
$this->addHoliday(new Holiday( |
|
352
|
|
|
'memorialDay', |
|
353
|
|
|
['en' => 'Memorial Day', 'ko' => '현충일'], |
|
354
|
|
|
new DateTime("$this->year-6-6", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
355
|
|
|
$this->locale |
|
356
|
|
|
)); |
|
357
|
|
|
} |
|
358
|
|
|
} |
|
359
|
|
|
|
|
360
|
|
|
/** |
|
361
|
|
|
* Constitution Day. |
|
362
|
|
|
* |
|
363
|
|
|
* Constitution Day is held on July 17th and established since 1949. |
|
364
|
|
|
* Officially, it is a strict national holiday, but government offices and banks work normally after 2008. |
|
365
|
|
|
* |
|
366
|
|
|
* @link https://en.wikipedia.org/wiki/Constitution_Day_(South_Korea) |
|
367
|
|
|
* |
|
368
|
|
|
* @throws \Exception |
|
369
|
|
|
*/ |
|
370
|
|
|
public function calculateConstitutionDay(): void |
|
371
|
|
|
{ |
|
372
|
|
|
if ($this->year >= 1949 && $this->year < 2008) { |
|
373
|
|
|
$this->addHoliday(new Holiday( |
|
374
|
|
|
'constitutionDay', |
|
375
|
|
|
['en' => 'Constitution Day', 'ko' => '제헌절'], |
|
376
|
|
|
new DateTime("$this->year-7-17", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
377
|
|
|
$this->locale |
|
378
|
|
|
)); |
|
379
|
|
|
} |
|
380
|
|
|
} |
|
381
|
|
|
|
|
382
|
|
|
/** |
|
383
|
|
|
* Liberation Day. Liberation Day is held on August 15th and established since 1949. |
|
384
|
|
|
* |
|
385
|
|
|
* @link https://en.wikipedia.org/wiki/National_Liberation_Day_of_Korea |
|
386
|
|
|
* |
|
387
|
|
|
* @throws \Exception |
|
388
|
|
|
*/ |
|
389
|
|
|
public function calculateLiberationDay(): void |
|
390
|
|
|
{ |
|
391
|
|
|
if ($this->year >= 1949) { |
|
392
|
|
|
$this->addHoliday(new Holiday( |
|
393
|
|
|
'liberationDay', |
|
394
|
|
|
['en' => 'Liberation Day', 'ko' => '광복절'], |
|
395
|
|
|
new DateTime("$this->year-8-15", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
396
|
|
|
$this->locale |
|
397
|
|
|
)); |
|
398
|
|
|
} |
|
399
|
|
|
} |
|
400
|
|
|
|
|
401
|
|
|
/** |
|
402
|
|
|
* Armed Forces Day. Armed Forces Day is held on October 1st and established since 1956. |
|
403
|
|
|
* |
|
404
|
|
|
* @link https://en.wikipedia.org/wiki/Armed_Forces_Day_(South_Korea) |
|
405
|
|
|
* |
|
406
|
|
|
* @throws \Exception |
|
407
|
|
|
*/ |
|
408
|
|
|
public function calculateArmedForcesDay(): void |
|
409
|
|
|
{ |
|
410
|
|
|
if ($this->year >= 1956 && $this->year <= 1990) { |
|
411
|
|
|
$this->addHoliday(new Holiday( |
|
412
|
|
|
'armedForcesDay', |
|
413
|
|
|
['en' => 'Armed Forces Day', 'ko' => '국군의 날'], |
|
414
|
|
|
new DateTime("$this->year-10-1", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
415
|
|
|
$this->locale |
|
416
|
|
|
)); |
|
417
|
|
|
} |
|
418
|
|
|
} |
|
419
|
|
|
|
|
420
|
|
|
/** |
|
421
|
|
|
* Gaecheonjeol (National Foundation Day). Gaecheonjeol is held on October 3rd and established since 1949. |
|
422
|
|
|
* |
|
423
|
|
|
* @link https://en.wikipedia.org/wiki/Gaecheonjeol |
|
424
|
|
|
* |
|
425
|
|
|
* @throws \Exception |
|
426
|
|
|
*/ |
|
427
|
|
|
public function calculateNationalFoundationDay(): void |
|
428
|
|
|
{ |
|
429
|
|
|
if ($this->year >= 1949) { |
|
430
|
|
|
$this->addHoliday(new Holiday( |
|
431
|
|
|
'nationalFoundationDay', |
|
432
|
|
|
['en' => 'National Foundation Day', 'ko' => '개천절'], |
|
433
|
|
|
new DateTime("$this->year-10-3", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
434
|
|
|
$this->locale |
|
435
|
|
|
)); |
|
436
|
|
|
} |
|
437
|
|
|
} |
|
438
|
|
|
|
|
439
|
|
|
/** |
|
440
|
|
|
* Hangul Day. Hangul Day is held on October 9th and established since 1949. |
|
441
|
|
|
* |
|
442
|
|
|
* @link https://en.wikipedia.org/wiki/Hangul_Day |
|
443
|
|
|
* |
|
444
|
|
|
* @throws \Exception |
|
445
|
|
|
*/ |
|
446
|
|
|
public function calculateHangulDay(): void |
|
447
|
|
|
{ |
|
448
|
|
|
if (($this->year >= 1949 && $this->year <= 1990) || $this->year > 2012) { |
|
449
|
|
|
$this->addHoliday(new Holiday( |
|
450
|
|
|
'hangulDay', |
|
451
|
|
|
['en' => 'Hangul Day', 'ko' => '한글날'], |
|
452
|
|
|
new DateTime("$this->year-10-9", DateTimeZoneFactory::getDateTimeZone($this->timezone)), |
|
453
|
|
|
$this->locale |
|
454
|
|
|
)); |
|
455
|
|
|
} |
|
456
|
|
|
} |
|
457
|
|
|
|
|
458
|
|
|
/** |
|
459
|
|
|
* Substitute Holidays. |
|
460
|
|
|
* Related statutes: Article 3 Alternative Statutory Holidays of the Regulations on Holidays of Government Offices |
|
461
|
|
|
* |
|
462
|
|
|
* Since 2014, it has been applied only on Seollal, Chuseok and Children's Day. |
|
463
|
|
|
* Due to the lunar calendar, public holidays can overlap even if it's not a Sunday. |
|
464
|
|
|
* When public holidays fall on each other, the first non-public holiday after the holiday becomes a public holiday. |
|
465
|
|
|
* As an exception, Children's Day also applies on Saturday. |
|
466
|
|
|
* |
|
467
|
|
|
* @throws \Exception |
|
468
|
|
|
*/ |
|
469
|
|
|
public function calculateSubstituteHolidays(): void |
|
470
|
|
|
{ |
|
471
|
|
|
if ($this->year <= 2013) { |
|
472
|
|
|
return; |
|
473
|
|
|
} |
|
474
|
|
|
|
|
475
|
|
|
// Initialize holidays variable |
|
476
|
|
|
$holidays = $this->getHolidays(); |
|
477
|
|
|
$acceptedHolidays = [ |
|
478
|
|
|
'dayBeforeSeollal', 'seollal', 'dayAfterSeollal', |
|
479
|
|
|
'dayBeforeChuseok', 'chuseok', 'dayAfterChuseok', |
|
480
|
|
|
'childrensDay', |
|
481
|
|
|
]; |
|
482
|
|
|
|
|
483
|
|
|
// Loop through all holidays |
|
484
|
|
|
foreach ($holidays as $key => $holiday) { |
|
485
|
|
|
// Get list of holiday dates except this |
|
486
|
|
|
$holidayDates = \array_map(static function ($holiday) use ($key) { |
|
487
|
|
|
return $holiday->getKey() === $key ? false : (string) $holiday; |
|
488
|
|
|
}, $holidays); |
|
489
|
|
|
|
|
490
|
|
|
// Only process accepted holidays and conditions |
|
491
|
|
|
if (\in_array($key, $acceptedHolidays, true) |
|
492
|
|
|
&& ( |
|
493
|
|
|
0 === (int) $holiday->format('w') |
|
494
|
|
|
|| \in_array($holiday, $holidayDates, false) |
|
495
|
|
|
|| (6 === (int) $holiday->format('w') && 'childrensDay' === $key) |
|
496
|
|
|
) |
|
497
|
|
|
) { |
|
498
|
|
|
$date = clone $holiday; |
|
499
|
|
|
|
|
500
|
|
|
// Find next week day (not being another holiday) |
|
501
|
|
|
while (0 === (int) $date->format('w') |
|
502
|
|
|
|| (6 === (int) $date->format('w') && 'childrensDay' === $key) |
|
503
|
|
|
|| \in_array($date, $holidayDates, false)) { |
|
504
|
|
|
$date->add(new DateInterval('P1D')); |
|
505
|
|
|
continue; |
|
506
|
|
|
} |
|
507
|
|
|
|
|
508
|
|
|
// Add a new holiday that is substituting the original holiday |
|
509
|
|
|
$substitute = new SubstituteHoliday( |
|
510
|
|
|
$holiday, |
|
511
|
|
|
[], |
|
512
|
|
|
$date, |
|
513
|
|
|
$this->locale |
|
514
|
|
|
); |
|
515
|
|
|
|
|
516
|
|
|
// Add a new holiday that is substituting the original holiday |
|
517
|
|
|
$this->addHoliday($substitute); |
|
518
|
|
|
|
|
519
|
|
|
// Add substitute holiday to the list |
|
520
|
|
|
$holidays[] = $substitute; |
|
521
|
|
|
} |
|
522
|
|
|
} |
|
523
|
|
|
} |
|
524
|
|
|
} |
|
525
|
|
|
|