Skip to content

Commit f308020

Browse files
timeshiftinghamrak
authored andcommitted
feat(new zealand): Add Matariki public holiday (azuyalabs#378)
Adds the Matariki public holiday that's been observed since 2022 Signed-off-by: Matt Gifford <matt@timeshifting.com> Signed-off-by: Ján Hamrák <hamrak@kcorp.sk>
1 parent d7cdde0 commit f308020

3 files changed

Lines changed: 235 additions & 0 deletions

File tree

src/Yasumi/Provider/NewZealand.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public function initialize(): void
5050
$this->calculateWaitangiDay();
5151
$this->calculateAnzacDay();
5252
$this->calculateQueensBirthday();
53+
$this->calculateMatariki();
5354
$this->calculateLabourDay();
5455

5556
// Add Christian holidays
@@ -194,6 +195,71 @@ protected function calculateQueensBirthday(): void
194195
));
195196
}
196197

198+
/**
199+
* Matariki – te Mātahi o te Tau
200+
* Matariki – the Māori New Year
201+
*
202+
* The Matariki public holiday is based on the winter rising of the Matariki cluster in the early
203+
* morning sky during the Tangaroa period of the lunar month of Pipiri.
204+
*
205+
* The dates are predetermined by the Matariki Advisory Committee, currently for the years 2022-2052 inclusive
206+
*
207+
* @see https://www.tepapa.govt.nz/discover-collections/read-watch-play/matariki-maori-new-year/dates-for-matariki-public-holiday
208+
* @see https://www.mbie.govt.nz/business-and-employment/employment-and-skills/employment-legislation-reviews/matariki/matariki-public-holiday
209+
*
210+
* @throws \InvalidArgumentException
211+
* @throws UnknownLocaleException
212+
* @throws \Exception
213+
*/
214+
protected function calculateMatariki(): void
215+
{
216+
if ($this->year < 2022 || 2052 < $this->year) {
217+
return;
218+
}
219+
220+
$matarikiDates = [
221+
2022 => ['month' => 6, 'day' => 24],
222+
2023 => ['month' => 7, 'day' => 14],
223+
2024 => ['month' => 6, 'day' => 28],
224+
2025 => ['month' => 6, 'day' => 20],
225+
2026 => ['month' => 7, 'day' => 10],
226+
2027 => ['month' => 6, 'day' => 25],
227+
2028 => ['month' => 7, 'day' => 14],
228+
2029 => ['month' => 7, 'day' => 6],
229+
2030 => ['month' => 6, 'day' => 21],
230+
2031 => ['month' => 7, 'day' => 11],
231+
2032 => ['month' => 7, 'day' => 2],
232+
2033 => ['month' => 6, 'day' => 24],
233+
2034 => ['month' => 7, 'day' => 7],
234+
2035 => ['month' => 6, 'day' => 29],
235+
2036 => ['month' => 7, 'day' => 18],
236+
2037 => ['month' => 7, 'day' => 10],
237+
2038 => ['month' => 6, 'day' => 25],
238+
2039 => ['month' => 7, 'day' => 15],
239+
2040 => ['month' => 7, 'day' => 6],
240+
2041 => ['month' => 7, 'day' => 19],
241+
2042 => ['month' => 7, 'day' => 11],
242+
2043 => ['month' => 7, 'day' => 3],
243+
2044 => ['month' => 6, 'day' => 24],
244+
2045 => ['month' => 7, 'day' => 7],
245+
2046 => ['month' => 6, 'day' => 29],
246+
2047 => ['month' => 7, 'day' => 19],
247+
2048 => ['month' => 7, 'day' => 3],
248+
2049 => ['month' => 6, 'day' => 25],
249+
2050 => ['month' => 7, 'day' => 15],
250+
2051 => ['month' => 6, 'day' => 30],
251+
2052 => ['month' => 6, 'day' => 21],
252+
];
253+
254+
$date = new \DateTime(
255+
sprintf('%04d-%02d-%02d', $this->year, $matarikiDates[$this->year]['month'],
256+
$matarikiDates[$this->year]['day']),
257+
DateTimeZoneFactory::getDateTimeZone($this->timezone)
258+
);
259+
260+
$this->addHoliday(new Holiday('matariki', [], $date, $this->locale));
261+
}
262+
197263
/**
198264
* During the 19th century, workers in New Zealand tried to claim the right for an 8-hour working day.
199265
* In 1840 carpenter Samuel Parnell fought for this right in Wellington, NZ, and won.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
/**
6+
* This file is part of the 'Yasumi' package.
7+
*
8+
* The easy PHP Library for calculating holidays.
9+
*
10+
* Copyright (c) 2015 - 2025 AzuyaLabs
11+
*
12+
* For the full copyright and license information, please view the LICENSE
13+
* file that was distributed with this source code.
14+
*
15+
* @author Sacha Telgenhof <me at sachatelgenhof dot com>
16+
*/
17+
18+
// Translations for Matariki
19+
return [
20+
'en' => 'Matariki',
21+
];

tests/NewZealand/MatarikiTest.php

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
/**
6+
* This file is part of the 'Yasumi' package.
7+
*
8+
* The easy PHP Library for calculating holidays.
9+
*
10+
* Copyright (c) 2015 - 2025 AzuyaLabs
11+
*
12+
* For the full copyright and license information, please view the LICENSE
13+
* file that was distributed with this source code.
14+
*
15+
* @author Sacha Telgenhof <me at sachatelgenhof dot com>
16+
*/
17+
18+
use Yasumi\Holiday;
19+
use Yasumi\tests\HolidayTestCase;
20+
21+
/**
22+
* Class for testing Matariki in the New Zealand.
23+
*/
24+
class MatarikiTest extends Yasumi\tests\NewZealand\NewZealandBaseTestCase implements HolidayTestCase
25+
{
26+
/**
27+
* The name of the holiday.
28+
*/
29+
public const HOLIDAY = 'matariki';
30+
31+
/**
32+
* The year in which the holiday was first established.
33+
*/
34+
public const ESTABLISHMENT_YEAR = 2022;
35+
36+
/**
37+
* The year the Matariki Advisory Committee have calculated dates until
38+
*/
39+
public const CALCULATED_UNTIL_YEAR = 2052;
40+
41+
/**
42+
* Tests Matariki.
43+
*
44+
* @dataProvider HolidayDataProvider
45+
*
46+
* @param int $year the year for which the holiday defined in this test needs to be tested
47+
* @param DateTime $expected the expected date
48+
*/
49+
public function testHoliday(int $year, DateTimeInterface $expected): void
50+
{
51+
$this->assertHoliday(self::REGION, self::HOLIDAY, $year, $expected);
52+
}
53+
54+
/**
55+
* Tests that Holiday is not present before 2022.
56+
*/
57+
public function testNotHoliday(): void
58+
{
59+
$this->assertNotHoliday(self::REGION, self::HOLIDAY, self::ESTABLISHMENT_YEAR - 1);
60+
}
61+
62+
/**
63+
* Returns a list of test dates.
64+
*
65+
* @return array<array> list of test dates for the holiday defined in this test
66+
*
67+
* @throws Exception
68+
*/
69+
public function HolidayDataProvider(): array
70+
{
71+
$data = [];
72+
73+
$matarikiDates = [
74+
2022 => ['month' => 6, 'day' => 24],
75+
2023 => ['month' => 7, 'day' => 14],
76+
2024 => ['month' => 6, 'day' => 28],
77+
2025 => ['month' => 6, 'day' => 20],
78+
2026 => ['month' => 7, 'day' => 10],
79+
2027 => ['month' => 6, 'day' => 25],
80+
2028 => ['month' => 7, 'day' => 14],
81+
2029 => ['month' => 7, 'day' => 6],
82+
2030 => ['month' => 6, 'day' => 21],
83+
2031 => ['month' => 7, 'day' => 11],
84+
2032 => ['month' => 7, 'day' => 2],
85+
2033 => ['month' => 6, 'day' => 24],
86+
2034 => ['month' => 7, 'day' => 7],
87+
2035 => ['month' => 6, 'day' => 29],
88+
2036 => ['month' => 7, 'day' => 18],
89+
2037 => ['month' => 7, 'day' => 10],
90+
2038 => ['month' => 6, 'day' => 25],
91+
2039 => ['month' => 7, 'day' => 15],
92+
2040 => ['month' => 7, 'day' => 6],
93+
2041 => ['month' => 7, 'day' => 19],
94+
2042 => ['month' => 7, 'day' => 11],
95+
2043 => ['month' => 7, 'day' => 3],
96+
2044 => ['month' => 6, 'day' => 24],
97+
2045 => ['month' => 7, 'day' => 7],
98+
2046 => ['month' => 6, 'day' => 29],
99+
2047 => ['month' => 7, 'day' => 19],
100+
2048 => ['month' => 7, 'day' => 3],
101+
2049 => ['month' => 6, 'day' => 25],
102+
2050 => ['month' => 7, 'day' => 15],
103+
2051 => ['month' => 6, 'day' => 30],
104+
2052 => ['month' => 6, 'day' => 21],
105+
];
106+
107+
for ($y = 1; $y <= 100; ++$y) {
108+
$year = $this->generateRandomYear(self::ESTABLISHMENT_YEAR, self::CALCULATED_UNTIL_YEAR);
109+
$expected = new DateTime(
110+
sprintf('%04d-%02d-%02d', $year, $matarikiDates[$year]['month'], $matarikiDates[$year]['day']),
111+
new DateTimeZone(self::TIMEZONE)
112+
);
113+
$data[] = [$year, $expected];
114+
}
115+
116+
return $data;
117+
}
118+
119+
/**
120+
* Tests the translated name of the holiday defined in this test.
121+
*
122+
* @throws Exception
123+
*/
124+
public function testTranslation(): void
125+
{
126+
$this->assertTranslatedHolidayName(
127+
self::REGION,
128+
self::HOLIDAY,
129+
$this->generateRandomYear(self::ESTABLISHMENT_YEAR, self::CALCULATED_UNTIL_YEAR),
130+
[self::LOCALE => 'Matariki']
131+
);
132+
}
133+
134+
/**
135+
* Tests type of the holiday defined in this test.
136+
*
137+
* @throws Exception
138+
*/
139+
public function testHolidayType(): void
140+
{
141+
$this->assertHolidayType(
142+
self::REGION,
143+
self::HOLIDAY,
144+
$this->generateRandomYear(self::ESTABLISHMENT_YEAR, self::CALCULATED_UNTIL_YEAR),
145+
Holiday::TYPE_OFFICIAL
146+
);
147+
}
148+
}

0 commit comments

Comments
 (0)