Skip to content

Commit 1ee8018

Browse files
committed
feat: add Venezuela holiday provider
Added a new hoiday provider for Venezuela (VE) with support for all official public holidays, test coverage, and Spanish locale translations. Signed-off-by: Sacha Telgenhof <me@sachatelgenhof.com>
1 parent 398caf6 commit 1ee8018

12 files changed

Lines changed: 1172 additions & 0 deletions

phpunit.xml.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@
194194
<testsuite name="Ukraine">
195195
<directory>./tests/Ukraine</directory>
196196
</testsuite>
197+
<!-- Test Suite for holidays in Venezuela -->
198+
<testsuite name="Venezuela">
199+
<directory>./tests/Venezuela</directory>
200+
</testsuite>
197201
<!-- Test Suite for holidays in United Kingdom -->
198202
<testsuite name="UnitedKingdom">
199203
<directory>./tests/UnitedKingdom</directory>

src/Yasumi/Provider/Venezuela.php

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
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 - 2026 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+
namespace Yasumi\Provider;
19+
20+
use Yasumi\Exception\UnknownLocaleException;
21+
use Yasumi\Holiday;
22+
23+
/**
24+
* Provider for all holidays in Venezuela.
25+
*
26+
* @see https://en.wikipedia.org/wiki/Public_holidays_in_Venezuela
27+
*/
28+
class Venezuela extends AbstractProvider
29+
{
30+
use CommonHolidays;
31+
use ChristianHolidays;
32+
33+
/**
34+
* The year when Venezuela declared independence from Spain.
35+
*/
36+
public const DECLARATION_OF_INDEPENDENCE_YEAR = 1811;
37+
38+
/**
39+
* Code to identify this Holiday Provider. Typically, this is the ISO3166 code corresponding to the respective
40+
* country or sub-region.
41+
*/
42+
public const ID = 'VE';
43+
44+
/**
45+
* Initialize holidays for Venezuela.
46+
*
47+
* @throws \InvalidArgumentException
48+
* @throws UnknownLocaleException
49+
* @throws \Exception
50+
*/
51+
public function initialize(): void
52+
{
53+
$this->timezone = 'America/Caracas';
54+
55+
// Add common holidays
56+
$this->addHoliday($this->newYearsDay($this->year, $this->timezone, $this->locale));
57+
$this->addHoliday($this->internationalWorkersDay($this->year, $this->timezone, $this->locale));
58+
59+
// Add Christian holidays
60+
$this->addHoliday($this->christmasDay($this->year, $this->timezone, $this->locale));
61+
$this->addHoliday($this->maundyThursday($this->year, $this->timezone, $this->locale));
62+
$this->addHoliday($this->goodFriday($this->year, $this->timezone, $this->locale));
63+
64+
// Calculate country-specific holidays
65+
$this->calculateCarnaval();
66+
$this->calculateDeclarationOfIndependence();
67+
$this->calculateBattleOfCarabobo();
68+
$this->calculateIndependenceDay();
69+
$this->calculateSimonBolivarBirthday();
70+
$this->calculateDayOfIndigenousResistance();
71+
$this->calculateChristmasEve();
72+
$this->calculateNewYearsEve();
73+
}
74+
75+
/**
76+
* Returns a list of sources for holiday calculations.
77+
*
78+
* @return string[] The source URLs
79+
*/
80+
public function getSources(): array
81+
{
82+
return [
83+
'https://en.wikipedia.org/wiki/Public_holidays_in_Venezuela',
84+
'https://www.timeanddate.com/holidays/venezuela/',
85+
'https://www.officeholidays.com/countries/venezuela',
86+
];
87+
}
88+
89+
/**
90+
* Carnaval (Carnival).
91+
*
92+
* Carnival is celebrated on Monday and Tuesday before Ash Wednesday.
93+
* It is one of the most important celebrations in Venezuela.
94+
*
95+
* @throws \Exception
96+
*/
97+
protected function calculateCarnaval(): void
98+
{
99+
if ($this->year >= 1700) {
100+
$easter = $this->calculateEaster($this->year, $this->timezone);
101+
102+
$days = [
103+
'carnavalMonday' => [
104+
'interval' => 'P48D',
105+
'name_es' => 'Lunes de Carnaval',
106+
'name_en' => 'Carnival Monday',
107+
],
108+
'carnavalTuesday' => [
109+
'interval' => 'P47D',
110+
'name_es' => 'Martes de Carnaval',
111+
'name_en' => 'Carnival Tuesday',
112+
],
113+
];
114+
115+
foreach ($days as $name => $day) {
116+
$date = (clone $easter)->sub(new \DateInterval($day['interval']));
117+
118+
if (! $date instanceof \DateTime) {
119+
throw new \RuntimeException(sprintf('unable to perform a date subtraction for %s:%s', self::class, $name));
120+
}
121+
122+
$this->addHoliday(new Holiday(
123+
$name,
124+
[
125+
'es' => $day['name_es'],
126+
'en' => $day['name_en'],
127+
],
128+
$date,
129+
$this->locale
130+
));
131+
}
132+
}
133+
}
134+
135+
/**
136+
* Declaration of Independence.
137+
*
138+
* On April 19, 1810, Venezuela began its independence movement by establishing a junta
139+
* that deposed the Spanish colonial authorities. This date marks the beginning of
140+
* Venezuelan independence.
141+
*
142+
* @see https://en.wikipedia.org/wiki/Venezuelan_Declaration_of_Independence
143+
*/
144+
protected function calculateDeclarationOfIndependence(): void
145+
{
146+
if ($this->year >= 1810) {
147+
$this->addHoliday(new Holiday(
148+
'declarationOfIndependence',
149+
[
150+
'es' => 'Declaración de la Independencia',
151+
'en' => 'Declaration of Independence',
152+
],
153+
new \DateTime("{$this->year}-04-19", DateTimeZoneFactory::getDateTimeZone($this->timezone)),
154+
$this->locale
155+
));
156+
}
157+
}
158+
159+
/**
160+
* Battle of Carabobo.
161+
*
162+
* The Battle of Carabobo was fought on June 24, 1821. It was the decisive battle
163+
* in the Venezuelan War of Independence that established the independence of Venezuela.
164+
*
165+
* @see https://en.wikipedia.org/wiki/Battle_of_Carabobo
166+
*/
167+
protected function calculateBattleOfCarabobo(): void
168+
{
169+
if ($this->year >= 1821) {
170+
$this->addHoliday(new Holiday(
171+
'battleOfCarabobo',
172+
[
173+
'es' => 'Batalla de Carabobo',
174+
'en' => 'Battle of Carabobo',
175+
],
176+
new \DateTime("{$this->year}-06-24", DateTimeZoneFactory::getDateTimeZone($this->timezone)),
177+
$this->locale
178+
));
179+
}
180+
}
181+
182+
/**
183+
* Independence Day.
184+
*
185+
* Venezuelan Independence Day is celebrated on July 5th, marking the day when
186+
* the Congress of Venezuela declared independence from Spain in 1811.
187+
*
188+
* @see https://en.wikipedia.org/wiki/Venezuelan_Independence
189+
*/
190+
protected function calculateIndependenceDay(): void
191+
{
192+
if ($this->year >= self::DECLARATION_OF_INDEPENDENCE_YEAR) {
193+
$this->addHoliday(new Holiday(
194+
'independenceDay',
195+
[
196+
'es' => 'Día de la Independencia',
197+
'en' => 'Independence Day',
198+
],
199+
new \DateTime("{$this->year}-07-05", DateTimeZoneFactory::getDateTimeZone($this->timezone)),
200+
$this->locale
201+
));
202+
}
203+
}
204+
205+
/**
206+
* Simon Bolivar's Birthday.
207+
*
208+
* Simon Bolivar was born on July 24, 1783 in Caracas. He is considered the
209+
* liberator of Venezuela, Colombia, Ecuador, Peru, and Bolivia.
210+
*
211+
* @see https://en.wikipedia.org/wiki/Simon_Bolivar
212+
*/
213+
protected function calculateSimonBolivarBirthday(): void
214+
{
215+
if ($this->year >= 1783) {
216+
$this->addHoliday(new Holiday(
217+
'simonBolivarBirthday',
218+
[
219+
'es' => 'Natalicio del Libertador',
220+
'en' => "Simon Bolivar\u{2019}s Birthday",
221+
],
222+
new \DateTime("{$this->year}-07-24", DateTimeZoneFactory::getDateTimeZone($this->timezone)),
223+
$this->locale
224+
));
225+
}
226+
}
227+
228+
/**
229+
* Day of Indigenous Resistance.
230+
*
231+
* Formerly known as "Columbus Day" or "Day of the Race" (Día de la Raza), this holiday
232+
* was renamed in 2002 to Day of Indigenous Resistance (Día de la Resistencia Indígena)
233+
* to honor the indigenous peoples who resisted European colonization.
234+
*
235+
* @see https://en.wikipedia.org/wiki/Day_of_Indigenous_Resistance
236+
*/
237+
protected function calculateDayOfIndigenousResistance(): void
238+
{
239+
if ($this->year >= 1921) {
240+
$this->addHoliday(new Holiday(
241+
'dayOfIndigenousResistance',
242+
[
243+
'es' => 'Día de la Resistencia Indígena',
244+
'en' => 'Day of Indigenous Resistance',
245+
],
246+
new \DateTime("{$this->year}-10-12", DateTimeZoneFactory::getDateTimeZone($this->timezone)),
247+
$this->locale
248+
));
249+
}
250+
}
251+
252+
/**
253+
* Christmas Eve.
254+
*
255+
* Christmas Eve (Nochebuena) is celebrated on December 24th and is an
256+
* important family celebration in Venezuela.
257+
*/
258+
protected function calculateChristmasEve(): void
259+
{
260+
$this->addHoliday(new Holiday(
261+
'christmasEve',
262+
[
263+
'es' => 'Nochebuena',
264+
'en' => 'Christmas Eve',
265+
],
266+
new \DateTime("{$this->year}-12-24", DateTimeZoneFactory::getDateTimeZone($this->timezone)),
267+
$this->locale
268+
));
269+
}
270+
271+
/**
272+
* New Year's Eve.
273+
*
274+
* New Year's Eve (Nochevieja) is celebrated on December 31st.
275+
*/
276+
protected function calculateNewYearsEve(): void
277+
{
278+
$this->addHoliday(new Holiday(
279+
'newYearsEve',
280+
[
281+
'es' => 'Nochevieja',
282+
'en' => "New Year\u{2019}s Eve",
283+
],
284+
new \DateTime("{$this->year}-12-31", DateTimeZoneFactory::getDateTimeZone($this->timezone)),
285+
$this->locale
286+
));
287+
}
288+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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 - 2026 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+
namespace Yasumi\tests\Venezuela;
19+
20+
use Yasumi\Holiday;
21+
use Yasumi\tests\HolidayTestCase;
22+
23+
/**
24+
* Class for testing Battle of Carabobo in Venezuela.
25+
*/
26+
class BattleOfCaraboboTest extends VenezuelaBaseTestCase implements HolidayTestCase
27+
{
28+
/**
29+
* The name of the holiday.
30+
*/
31+
public const HOLIDAY = 'battleOfCarabobo';
32+
33+
/**
34+
* The year in which the holiday was first established.
35+
*/
36+
public const ESTABLISHMENT_YEAR = 1821;
37+
38+
/**
39+
* Tests Battle of Carabobo on or after 1821.
40+
*
41+
* @throws \Exception
42+
*/
43+
public function testBattleOfCaraboboAfter1821(): void
44+
{
45+
$year = static::generateRandomYear(self::ESTABLISHMENT_YEAR);
46+
$this->assertHoliday(
47+
self::REGION,
48+
self::HOLIDAY,
49+
$year,
50+
new \DateTime("{$year}-06-24", new \DateTimeZone(self::TIMEZONE))
51+
);
52+
}
53+
54+
/**
55+
* Tests Battle of Carabobo before 1821.
56+
*
57+
* @throws \Exception
58+
*/
59+
public function testBattleOfCaraboboBefore1821(): void
60+
{
61+
$year = static::generateRandomYear(1000, self::ESTABLISHMENT_YEAR - 1);
62+
$this->assertNotHoliday(self::REGION, self::HOLIDAY, $year);
63+
}
64+
65+
/**
66+
* Tests the translated name of the holiday defined in this test.
67+
*
68+
* @throws \Exception
69+
*/
70+
public function testTranslation(): void
71+
{
72+
$year = static::generateRandomYear(self::ESTABLISHMENT_YEAR);
73+
$this->assertTranslatedHolidayName(
74+
self::REGION,
75+
self::HOLIDAY,
76+
$year,
77+
[self::LOCALE => 'Batalla de Carabobo']
78+
);
79+
}
80+
81+
/**
82+
* Tests type of the holiday defined in this test.
83+
*
84+
* @throws \Exception
85+
*/
86+
public function testHolidayType(): void
87+
{
88+
$year = static::generateRandomYear(self::ESTABLISHMENT_YEAR);
89+
$this->assertHolidayType(self::REGION, self::HOLIDAY, $year, Holiday::TYPE_OFFICIAL);
90+
}
91+
}

0 commit comments

Comments
 (0)