Australia::initialize()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 11
rs 10
cc 1
nc 1
nop 0
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the Yasumi package.
4
 *
5
 * Copyright (c) 2015 - 2020 AzuyaLabs
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @author Sacha Telgenhof <[email protected]>
11
 */
12
13
namespace Yasumi\Provider;
14
15
use DateInterval;
16
use DateTime;
17
use Yasumi\Exception\UnknownLocaleException;
18
use Yasumi\Holiday;
19
use Yasumi\SubstituteHoliday;
20
21
/**
22
 * Provider for all holidays in Australia.
23
 */
24
class Australia extends AbstractProvider
25
{
26
    use CommonHolidays, ChristianHolidays;
27
28
    /**
29
     * Code to identify this Holiday Provider. Typically this is the ISO3166 code corresponding to the respective
30
     * country or sub-region.
31
     */
32
    public const ID = 'AU';
33
34
    public $timezone = 'Australia/Melbourne';
35
36
    /**
37
     * Initialize holidays for Australia.
38
     *
39
     * @throws \InvalidArgumentException
40
     * @throws UnknownLocaleException
41
     * @throws \Exception
42
     */
43
    public function initialize(): void
44
    {
45
        // Official Holidays
46
        $this->calculateNewYearHolidays();
47
        $this->calculateAustraliaDay();
48
        $this->calculateAnzacDay();
49
50
        // Add Christian holidays
51
        $this->addHoliday($this->goodFriday($this->year, $this->timezone, $this->locale));
52
        $this->addHoliday($this->easterMonday($this->year, $this->timezone, $this->locale));
53
        $this->calculateChristmasDay();
54
    }
55
56
    /**
57
     * Holidays associated with the start of the modern Gregorian calendar.
58
     *
59
     * New Year's Day is on January 1 and is the first day of a new year in the Gregorian calendar,
60
     * which is used in Australia and many other countries. Due to its geographical position close
61
     * to the International Date Line, Australia is one of the first countries in the world to welcome the New Year.
62
     * If it falls on a weekend an additional public holiday is held on the next available weekday.
63
     *
64
     * @link https://www.timeanddate.com/holidays/australia/new-year-day
65
     *
66
     * @throws \InvalidArgumentException
67
     * @throws UnknownLocaleException
68
     * @throws \Exception
69
     */
70
    private function calculateNewYearHolidays(): void
71
    {
72
        $newYearsDay = new DateTime("$this->year-01-01", DateTimeZoneFactory::getDateTimeZone($this->timezone));
73
        $this->addHoliday(new Holiday(
74
            'newYearsDay',
75
            [],
76
            $newYearsDay,
77
            $this->locale,
78
            Holiday::TYPE_OFFICIAL
79
        ));
80
        switch ($newYearsDay->format('w')) {
81
            case 0: // sunday
82
                $newYearsDay->add(new DateInterval('P1D'));
83
                $this->addHoliday(new Holiday(
84
                    'newYearsHoliday',
85
                    ['en' => 'New Year’s Holiday'],
86
                    $newYearsDay,
87
                    $this->locale,
88
                    Holiday::TYPE_OFFICIAL
89
                ));
90
                break;
91
            case 6: // saturday
92
                $newYearsDay->add(new DateInterval('P2D'));
93
                $this->addHoliday(new Holiday(
94
                    'newYearsHoliday',
95
                    ['en' => 'New Year’s Holiday'],
96
                    $newYearsDay,
97
                    $this->locale,
98
                    Holiday::TYPE_OFFICIAL
99
                ));
100
                break;
101
        }
102
    }
103
104
    /**
105
     * Australia Day.
106
     *
107
     * Australia Day is the official National Day of Australia. Celebrated annually on 26 January,
108
     * it marks the anniversary of the 1788 arrival of the First Fleet of British Ships at
109
     * Port Jackson, New South Wales, and the raising of the Flag of Great Britain at Sydney Cove
110
     * by Governor Arthur Phillip. In present-day Australia, celebrations reflect the diverse
111
     * society and landscape of the nation, and are marked by community and family events,
112
     * reflections on Australian history, official community awards, and citizenship ceremonies
113
     * welcoming new immigrants into the Australian community.
114
     *
115
     * @link https://en.wikipedia.org/wiki/Waitangi_Day
116
     * @link https://www.timeanddate.com/holidays/australia/australia-day
117
     *
118
     * @throws \InvalidArgumentException
119
     * @throws UnknownLocaleException
120
     * @throws \Exception
121
     */
122
    private function calculateAustraliaDay(): void
123
    {
124
        $date = new DateTime("$this->year-01-26", DateTimeZoneFactory::getDateTimeZone($this->timezone));
125
126
        $holiday = new Holiday(
127
            'australiaDay',
128
            ['en' => 'Australia Day'],
129
            $date,
130
            $this->locale,
131
            Holiday::TYPE_OFFICIAL
132
        );
133
        $this->addHoliday($holiday);
134
135
        $day = (int) $date->format('w');
136
        if (0 === $day || 6 === $day) {
137
            $date = $date->add(0 === $day ? new DateInterval('P1D') : new DateInterval('P2D'));
138
139
            $this->addHoliday(new SubstituteHoliday(
140
                $holiday,
141
                [],
142
                $date,
143
                $this->locale,
144
                Holiday::TYPE_OFFICIAL
145
            ));
146
        }
147
    }
148
149
    /**
150
     * ANZAC Day.
151
     *
152
     * Anzac Day is a national day of remembrance in Australia and New Zealand that broadly commemorates all Australians
153
     * and New Zealanders "who served and died in all wars, conflicts, and peacekeeping operations"
154
     * Observed on 25 April each year. Unlike most other Australian public holidays, If it falls on a weekend it is NOT moved
155
     * to the next available weekday, nor is there an additional public holiday held. However, if it clashes with Easter,
156
     * an additional public holiday is held for Easter.
157
     *
158
     * @link https://en.wikipedia.org/wiki/Anzac_Day
159
     * @link https://www.timeanddate.com/holidays/australia/anzac-day
160
     *
161
     * @throws \InvalidArgumentException
162
     * @throws UnknownLocaleException
163
     * @throws \Exception
164
     */
165
    private function calculateAnzacDay(): void
166
    {
167
        if ($this->year < 1921) {
168
            return;
169
        }
170
171
        $date = new DateTime("$this->year-04-25", DateTimeZoneFactory::getDateTimeZone($this->timezone));
172
        $this->addHoliday(new Holiday(
173
            'anzacDay',
174
            [],
175
            $date,
176
            $this->locale,
177
            Holiday::TYPE_OFFICIAL
178
        ));
179
        $easter = $this->calculateEaster($this->year, $this->timezone);
180
181
        $easterMonday = $this->calculateEaster($this->year, $this->timezone);
182
        $easterMonday->add(new DateInterval('P1D'));
183
184
        $fDate = $date->format('Y-m-d');
185
        if ($fDate === $easter->format('Y-m-d') || $fDate === $easterMonday->format('Y-m-d')) {
186
            $easterMonday->add(new DateInterval('P1D'));
187
            $this->addHoliday(new Holiday(
188
                'easterTuesday',
189
                ['en' => 'Easter Tuesday'],
190
                $easterMonday,
191
                $this->locale,
192
                Holiday::TYPE_OFFICIAL
193
            ));
194
        }
195
    }
196
197
    /**
198
     * Christmas Day / Boxing Day.
199
     *
200
     * Christmas day, and Boxing day are public holidays in Australia,
201
     * if they fall on the weekend an additional public holiday is held on the next available weekday.
202
     *
203
     * @link https://www.timeanddate.com/holidays/australia/christmas-day-holiday
204
     *
205
     * @throws \InvalidArgumentException
206
     * @throws UnknownLocaleException
207
     * @throws \Exception
208
     */
209
    private function calculateChristmasDay(): void
210
    {
211
        $christmasDay = new DateTime("$this->year-12-25", DateTimeZoneFactory::getDateTimeZone($this->timezone));
212
        $boxingDay = new DateTime("$this->year-12-26", DateTimeZoneFactory::getDateTimeZone($this->timezone));
213
        $this->addHoliday(new Holiday(
214
            'christmasDay',
215
            [],
216
            $christmasDay,
217
            $this->locale,
218
            Holiday::TYPE_OFFICIAL
219
        ));
220
        $this->addHoliday(new Holiday(
221
            'secondChristmasDay',
222
            [],
223
            $boxingDay,
224
            $this->locale,
225
            Holiday::TYPE_OFFICIAL
226
        ));
227
228
        switch ($christmasDay->format('w')) {
229
            case 0: // sunday
230
                $christmasDay->add(new DateInterval('P2D'));
231
                $this->addHoliday(new Holiday(
232
                    'christmasHoliday',
233
                    ['en' => 'Christmas Holiday'],
234
                    $christmasDay,
235
                    $this->locale,
236
                    Holiday::TYPE_OFFICIAL
237
                ));
238
                break;
239
            case 5: // friday
240
                $boxingDay->add(new DateInterval('P2D'));
241
                $this->addHoliday(new Holiday(
242
                    'secondChristmasHoliday',
243
                    ['en' => 'Boxing Day Holiday'],
244
                    $boxingDay,
245
                    $this->locale,
246
                    Holiday::TYPE_OFFICIAL
247
                ));
248
                break;
249
            case 6: // saturday
250
                $christmasDay->add(new DateInterval('P2D'));
251
                $boxingDay->add(new DateInterval('P2D'));
252
                $this->addHoliday(new Holiday(
253
                    'christmasHoliday',
254
                    ['en' => 'Christmas Holiday'],
255
                    $christmasDay,
256
                    $this->locale,
257
                    Holiday::TYPE_OFFICIAL
258
                ));
259
                $this->addHoliday(new Holiday(
260
                    'secondChristmasHoliday',
261
                    ['en' => 'Boxing Day Holiday'],
262
                    $boxingDay,
263
                    $this->locale,
264
                    Holiday::TYPE_OFFICIAL
265
                ));
266
                break;
267
        }
268
    }
269
}
270