Skip to content

Commit

Permalink
Merge branch 'spatie:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
petersowah authored Jan 25, 2024
2 parents 0bf7438 + 076b619 commit 2b2deb7
Show file tree
Hide file tree
Showing 34 changed files with 1,236 additions and 11 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ use Spatie\Holidays\Holidays;
$holidays = Holidays::for(country: 'be', year: 2024))->get();
```

### Getting holidays in a specific language

```php
use Spatie\Holidays\Holidays;

$holidays = Holidays::for(country: 'be', locale: 'fr'))->get();
```

If the locale is not supported for a country, an exception will be thrown.

### Determining if a date is a holiday

If you need to see if a date is a holiday, you can use the `isHoliday` method.
Expand Down Expand Up @@ -112,6 +122,7 @@ This is a community driven package. If you find any errors, please create an iss
2. Add a test for the new country in the `tests` directory.
3. Run the tests so a snapshot gets created.
4. Verify the result in the newly created snapshot is correct.
5. If the country has multiple languages, add a file in the `lang/` directory.

In case your country has specific rules for calculating holidays,
for example region specific holidays, you can pass this to the constructor of your country class.
Expand Down
12 changes: 12 additions & 0 deletions lang/belgium/fr/holidays.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Nieuwjaar": "Jour de l'An",
"Dag van de Arbeid": "Fête du Travail",
"Nationale Feestdag": "Fête nationale",
"OLV Hemelvaart": "Assomption",
"Allerheiligen": "Toussaint",
"Wapenstilstand": "Armistice",
"Kerstmis": "Noël",
"Paasmaandag": "Lundi de Pâques",
"OLH Hemelvaart": "Ascension",
"Pinkstermaandag": "Lundi de Pentecôte"
}
15 changes: 15 additions & 0 deletions lang/finland/sv/holidays.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"Uudenvuodenpäivä": "Nyårsdagen",
"Loppiainen": "Trettondagen",
"Pitkäperjantai": "Långfredagen",
"Pääsiäispäivä": "Påskdagen",
"Toinen pääsiäispäivä": "Annandag påsk",
"Vappu": "Första maj",
"Helatorstai": "Kristi himmelsfärdsdag",
"Helluntaipäivä": "Pingst",
"Juhannuspäivä": "Midsommardagen",
"Pyhäinpäivä": "Alla helgons dag",
"Itsenäisyyspäivä": "Självständighetsdagen",
"Joulupäivä": "Juldagen",
"Tapaninpäivä": "Annandag jul"
}
32 changes: 32 additions & 0 deletions src/Concerns/Translatable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Spatie\Holidays\Concerns;

use Spatie\Holidays\Exceptions\InvalidLocale;

trait Translatable
{
protected function translate(string $country, string $name, ?string $locale = null): string
{
if ($locale === null) {
return $name;
}

$countryName = strtolower($country);

$content = file_get_contents(__DIR__."/../../lang/{$countryName}/{$locale}/holidays.json");

if ($content === false) {
throw InvalidLocale::notFound($country, $locale);
}

/** @var array<string, string> $data */
$data = json_decode($content, true);

if (! isset($data[$name])) {
return $name;
}

return $data[$name];
}
}
57 changes: 57 additions & 0 deletions src/Countries/Colombia.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace Spatie\Holidays\Countries;

use Carbon\CarbonImmutable;

class Colombia extends Country
{
public function countryCode(): string
{
return 'co';
}

protected function allHolidays(int $year): array
{
return array_merge([
'Año Nuevo' => '01-01',
'Día del Trabajo' => '05-01',
'Día de la independencia' => '07-20',
'Batalla de Boyacá' => '08-07',
'Inmaculada Concepción' => '12-08',
'Navidad' => '12-25',
], $this->variableHolidays($year));
}

/** @return array<string, CarbonImmutable> */
protected function variableHolidays(int $year): array
{
$easter = $this->easter($year);

return [
'Jueves Santo' => $easter->subDays(3),
'Viernes Santo' => $easter->subDays(2),
'Ascención de Jesús' => $easter->addDays(43),
'Corpus Christi' => $easter->addDays(64),
'Sagrado corazón de Jesús' => $easter->addDays(71),
'Reyes Magos' => $this->emilianiHoliday($year, 1, 6),
'Día de San José' => $this->emilianiHoliday($year, 3, 19),
'San Pedro y San Pablo' => $this->emilianiHoliday($year, 6, 29),
'Asunción de la Virgen' => $this->emilianiHoliday($year, 8, 15),
'Día de la raza' => $this->emilianiHoliday($year, 10, 12),
'Todos los santos' => $this->emilianiHoliday($year, 11, 1),
'Independencia de Cartagena' => $this->emilianiHoliday($year, 11, 11),

];
}

private function emilianiHoliday(int $year, int $month, int $day): CarbonImmutable
{
$dateObj = CarbonImmutable::createFromDate($year, $month, $day, 'America/Bogota')->startOfDay();
if ($dateObj->is('Monday')) {
return $dateObj;
} else {
return $dateObj->next('Monday');
}
}
}
18 changes: 12 additions & 6 deletions src/Countries/Country.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,42 @@
namespace Spatie\Holidays\Countries;

use Carbon\CarbonImmutable;
use Spatie\Holidays\Concerns\Translatable;
use Spatie\Holidays\Exceptions\InvalidYear;
use Spatie\Holidays\Exceptions\UnsupportedCountry;

abstract class Country
{
use Translatable;

abstract public function countryCode(): string;

/** @return array<string, string|CarbonImmutable> */
abstract protected function allHolidays(int $year): array;

/** @return array<string, CarbonImmutable|string> */
public function get(int $year): array
public function get(int $year, ?string $locale = null): array
{
$this->ensureYearCanBeCalculated($year);

$allHolidays = $this->allHolidays($year);

$allHolidays = array_map(function ($date) use ($year) {
$translatedHolidays = [];
foreach ($allHolidays as $name => $date) {
if (is_string($date)) {
$date = CarbonImmutable::createFromFormat('Y-m-d', "{$year}-{$date}");
}

return $date;
}, $allHolidays);
$name = $this->translate(basename(str_replace('\\', '/', static::class)), $name, $locale);

$translatedHolidays[$name] = $date;
}

uasort($allHolidays,
uasort($translatedHolidays,
fn (CarbonImmutable $a, CarbonImmutable $b) => $a->timestamp <=> $b->timestamp
);

return $allHolidays;
return $translatedHolidays;
}

public static function make(): static
Expand Down
40 changes: 40 additions & 0 deletions src/Countries/ElSalvador.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Spatie\Holidays\Countries;

use Carbon\CarbonImmutable;

class ElSalvador extends Country
{
public function countryCode(): string
{
return 'sv';
}

protected function allHolidays(int $year): array
{
return array_merge([
'Año Nuevo' => '01-01',
'Día del Trabajo' => '05-01',
'Día de la Madre' => '05-10',
'Día del Padre' => '06-17',
'Fiesta Divino Salvador del Mundo' => '08-06',
'Día de la Independencia' => '09-15',
'Día de Los Difuntos' => '11-02',
'Navidad' => '12-25',
], $this->variableHolidays($year));
}

/** @return array<string, CarbonImmutable> */
protected function variableHolidays(int $year): array
{
$easter = CarbonImmutable::createFromTimestamp(easter_date($year))
->setTimezone('America/El_Salvador');

return [
'Jueves Santo' => $easter->subDays(3),
'Viernes Santo' => $easter->subDays(2),
'Sábado de Gloria' => $easter->subDays(1),
];
}
}
54 changes: 54 additions & 0 deletions src/Countries/Finland.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Spatie\Holidays\Countries;

use Carbon\CarbonImmutable;

class Finland extends Country
{
public function countryCode(): string
{
return 'fi';
}

protected function allHolidays(int $year): array
{
return array_merge($this->fixedHolidays($year), $this->variableHolidays($year));
}

/** @return array<string, CarbonImmutable> */
protected function fixedHolidays(int $year): array
{
return [
'Uudenvuodenpäivä' => CarbonImmutable::createFromDate($year, 1, 1),
'Loppiainen' => CarbonImmutable::createFromDate($year, 1, 6),
'Vappu' => CarbonImmutable::createFromDate($year, 5, 1),
'Itsenäisyyspäivä' => CarbonImmutable::createFromDate($year, 12, 6),
'Joulupäivä' => CarbonImmutable::createFromDate($year, 12, 25),
'Tapaninpäivä' => CarbonImmutable::createFromDate($year, 12, 26),
];
}

/** @return array<string, CarbonImmutable> */
protected function variableHolidays(int $year): array
{
$easter = CarbonImmutable::createFromTimestamp(easter_date($year))
->setTimezone('Europe/Helsinki');

$midsummerDay = CarbonImmutable::createFromDate($year, 6, 20)
->next(CarbonImmutable::SATURDAY);

return [
'Pitkäperjantai' => $easter->subDays(2),
'Pääsiäispäivä' => $easter,
'Toinen pääsiäispäivä' => $easter->addDay(),
'Helatorstai' => $easter->addDays(39),
'Helluntaipäivä' => $easter->addDays(49),
'Juhannuspäivä' => $midsummerDay->day > 26
? $midsummerDay->subWeek()
: $midsummerDay,
'Pyhäinpäivä' => CarbonImmutable::createFromDate($year, 10, 31)
->next(CarbonImmutable::SATURDAY),
];
}
}
58 changes: 58 additions & 0 deletions src/Countries/Japan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Spatie\Holidays\Countries;

use Carbon\CarbonImmutable;

class Japan extends Country
{
public function countryCode(): string
{
return 'jp';
}

protected function allHolidays(int $year): array
{
return array_merge([
'元日' => '01-01', // New Year's Day
'建国記念の日' => '02-11', // Foundation Day
'天皇誕生日' => '02-23', // Emperor's Birthday
'春分の日' => '03-20', // Vernal Equinox Day *Decided each year; rarely on 03-21
'昭和の日' => '04-29', // Showa Day
'憲法記念日' => '05-03', // Constitution Day
'みどりの日' => '05-04', // Greenery Day
'こどもの日' => '05-05', // Children's Day
'山の日' => '08-11', // Mountain Day
'秋分の日' => '09-23', // Autumnal Equinox Day *Decided each year; rarely on 09-22
'文化の日' => '11-03', // Culture Day
'勤労感謝の日' => '11-23', // Labor Thanksgiving Day

], $this->variableHolidays($year));
}

/** @return array<string, CarbonImmutable> */
protected function variableHolidays(int $year): array
{
$comingOfAgeDay = (new CarbonImmutable("second monday of january $year")) // Coming of Age Day
->setTimezone('Asia/Tokyo');

$oceansDay = (new CarbonImmutable("third monday of july $year")) // Ocean's Day
->setTimezone('Asia/Tokyo');

$respectForTheAgedDay = (new CarbonImmutable("third monday of september $year")) // Respect for the Aged Day
->setTimezone('Asia/Tokyo');

$sportsDay = (new CarbonImmutable("second monday of october $year")) // Sports Day
->setTimezone('Asia/Tokyo');

$holidays = [
'成人の日' => $comingOfAgeDay,
'海の日' => $oceansDay,
'敬老の日' => $respectForTheAgedDay,
'スポーツの日' => $sportsDay,
];

return $holidays;

}
}
Loading

0 comments on commit 2b2deb7

Please sign in to comment.