generated from spatie/package-skeleton-php
-
-
Notifications
You must be signed in to change notification settings - Fork 199
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add-Moroccan-holidays * integrate hijri-dates to calculate Islamic Holidays * Fix PHPStan failures in GitHub Actions * Refactor: Removed dependency on geniusts/hijri-dates package and integrated the calculation function from the Ministry of Endowments and Islamic Affairs. * Add translations for holiday names, include missing holiday, and fix unit test coverage for the new holiday addition * Fix PHPStan issues & Code Style
- Loading branch information
1 parent
7d60ff9
commit dce5e2a
Showing
7 changed files
with
506 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"New Year\\'s Day": "رأس السنة الميلادية", | ||
"Proclamation of Independence Day": "تقديم وثيقة الاستقلال", | ||
"Amazigh New Year (ⵉⴹ ⵏ ⵢⵉⵏⵏⴰⵢⵔ)": "رأس السنة الأمازيغية", | ||
"Labour Day": "عيد الشغل", | ||
"Throne Day": "عيد العرش", | ||
"Oued Ed-Dahab Day": "استرجاع إقليم وادي الذهب", | ||
"Revolution Day": "ثورة الملك والشعب", | ||
"Youth Day": "عيد الشباب", | ||
"Green March": "ذكرى المسيرة الخضراء", | ||
"Independence Day": "عيد الاستقلال", | ||
"Islamic New Year": "رأس السنة الهجرية", | ||
"Birthday of the Prophet Muhammad": "عيد المولد النبوي", | ||
"Birthday of the Prophet Muhammad 2": "تاني ايام عيد المولد النبوي", | ||
"Eid al-Fitr": "عيد الفطر", | ||
"Eid al-Fitr 2": "تاني ايام عيد الفطر", | ||
"Eid al-Adha": "عيد الأضحى", | ||
"Eid al-Adha 2": "تاني ايام عيد الأضحى" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
<?php | ||
|
||
namespace Spatie\Holidays\Countries; | ||
|
||
use Carbon\CarbonImmutable; | ||
use Spatie\Holidays\Concerns\Translatable; | ||
use Spatie\Holidays\Contracts\HasTranslations; | ||
use Spatie\Holidays\Exceptions\InvalidYear; | ||
|
||
class Morocco extends Country implements HasTranslations | ||
{ | ||
use Translatable; | ||
|
||
public function countryCode(): string | ||
{ | ||
return 'ma'; | ||
} | ||
|
||
public function defaultLocale(): string | ||
{ | ||
return 'en'; | ||
} | ||
|
||
protected function allHolidays(int $year): array | ||
{ | ||
return array_merge([ | ||
'New Year\'s Day' => '01-01', | ||
'Proclamation of Independence Day' => '01-11', | ||
'Amazigh New Year (ⵉⴹ ⵏ ⵢⵉⵏⵏⴰⵢⵔ)' => '01-14', | ||
'Labour Day' => '05-01', | ||
'Throne Day' => '07-30', | ||
'Oued Ed-Dahab Day' => '08-14', | ||
'Revolution Day' => '08-20', | ||
'Youth Day' => '08-21', | ||
'Green March' => '11-06', | ||
'Independence Day' => '11-18', | ||
], $this->variableHolidays($year)); | ||
} | ||
|
||
/** @return array<string, CarbonImmutable> */ | ||
protected function variableHolidays(int $year): array | ||
{ | ||
// Calculate the current Hijri year based on the Gregorian year | ||
$currentHijriYear = 1444 + ($year - 2022); | ||
|
||
/** | ||
* The following holidays are considered public holidays in Morocco. However, their dates vary each year, | ||
* as they are based on the Islamic Hijri (lunar) calendar. These holidays do not have a fixed date and | ||
* occur based on the lunar calendar sequence. The order listed reflects the chronological occurrence | ||
* of these holidays throughout the year. | ||
*/ | ||
|
||
// Define Islamic holidays on the Hijri calendar | ||
$islamicHolidaysOnHijri = [ | ||
'Islamic New Year' => '01-01', | ||
'Birthday of the Prophet Muhammad' => '03-12', | ||
'Birthday of the Prophet Muhammad 2' => '03-13', | ||
'Eid al-Fitr' => '10-01', | ||
'Eid al-Fitr 2' => '10-02', | ||
'Eid al-Adha' => '12-10', | ||
'Eid al-Adha 2' => '12-11', | ||
]; | ||
|
||
$islamicHolidaysOnGregorian = []; | ||
// Convert Hijri dates to Gregorian and filter based on the input year | ||
foreach ($islamicHolidaysOnHijri as $holidayTitle => $hijriHolidayDate) { | ||
[$hijriHolidayMonth, $hijriHolidayDay] = explode('-', $hijriHolidayDate); | ||
$vlideYear = null; | ||
|
||
$GregorianDate = $this->islamicToGregorian($currentHijriYear, (int) $hijriHolidayMonth, (int) $hijriHolidayDay); | ||
$vlideYear = $GregorianDate['year']; | ||
$tempCurrentHijriYear = $currentHijriYear; | ||
while ($vlideYear != $year) { | ||
// Convert the current Hijri holiday to Gregorian | ||
$GregorianDate = $this->islamicToGregorian($tempCurrentHijriYear--, (int) $hijriHolidayMonth, (int) $hijriHolidayDay); | ||
$vlideYear = $GregorianDate['year']; | ||
if ($vlideYear < 1976) { | ||
throw InvalidYear::yearTooLow(1976); | ||
} | ||
} | ||
// Store the Gregorian date of the Islamic holiday | ||
$islamicHolidaysOnGregorian[$holidayTitle] = CarbonImmutable::createFromFormat('Y-m-d', sprintf('%s-%s-%s', $GregorianDate['year'], $GregorianDate['month'], $GregorianDate['day'])); | ||
} | ||
|
||
return $islamicHolidaysOnGregorian; | ||
} | ||
|
||
/** | ||
* Converts a Hijri date to the corresponding Gregorian date. | ||
* This function is adapted from the conversion tool used on the Moroccan | ||
* Minister of Endowments and Islamic Affairs official website. | ||
* https://www.habous.gov.ma/محول-التاريخ | ||
* | ||
* @param int $y The Hijri year. | ||
* @param int $m The Hijri month. | ||
* @param int $d The Hijri day. | ||
* @return array{year: int, month: int, day: int} An array containing the corresponding Gregorian date in the format ['year' => YYYY, 'month' => MM, 'day' => DD]. | ||
*/ | ||
private function islamicToGregorian(int $y, int $m, int $d): array | ||
{ | ||
$delta = 0; | ||
$jd = $this->intPart((11 * $y + 3) / 30) + 354 * $y + 30 * $m - $this->intPart(($m - 1) / 2) + $d + 1948440 - 385 + $delta; | ||
if ($jd > 2299160) { | ||
$l = $jd + 68569; | ||
$n = $this->intPart((4 * $l) / 146097); | ||
$l = $l - $this->intPart((146097 * $n + 3) / 4); | ||
$i = $this->intPart((4000 * ($l + 1)) / 1461001); | ||
$l = $l - $this->intPart((1461 * $i) / 4) + 31; | ||
$j = $this->intPart((80 * $l) / 2447); | ||
$d = $l - $this->intPart((2447 * $j) / 80); | ||
$l = $this->intPart($j / 11); | ||
$m = $j + 2 - 12 * $l; | ||
$y = 100 * ($n - 49) + $i + $l; | ||
} else { | ||
$j = $jd + 1402; | ||
$k = $this->intPart(($j - 1) / 1461); | ||
$l = $j - 1461 * $k; | ||
$n = $this->intPart(($l - 1) / 365) - $this->intPart($l / 1461); | ||
$i = $l - 365 * $n + 30; | ||
$j = $this->intPart((80 * $i) / 2447); | ||
$d = $i - $this->intPart((2447 * $j) / 80); | ||
$i = $this->intPart($j / 11); | ||
$m = $j + 2 - 12 * $i; | ||
$y = 4 * $k + $n + $i - 4716; | ||
} | ||
|
||
return [ | ||
'year' => (int) $y, | ||
'month' => (int) $m, | ||
'day' => (int) $d, | ||
]; | ||
} | ||
|
||
/** | ||
* Rounds a floating-point number to the nearest integer. | ||
* If the floating-point number is negative, it uses ceil function. | ||
* If the floating-point number is positive, it uses floor function. | ||
* | ||
* @param float $floatNum The floating-point number to be rounded. | ||
* @return float The rounded integer value. | ||
*/ | ||
private function intPart($floatNum) | ||
{ | ||
// Check if the floating-point number is negative | ||
if ($floatNum < -0.0000001) { | ||
// If negative, round up using ceil | ||
return ceil($floatNum - 0.0000001); | ||
} | ||
|
||
// If positive or zero, round down using floor | ||
return floor($floatNum + 0.0000001); | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
tests/.pest/snapshots/Countries/MoroccoTest/it_can_calculate_morocco_holidays_2023.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
[ | ||
{ | ||
"name": "New Year's Day", | ||
"date": "2023-01-01" | ||
}, | ||
{ | ||
"name": "Proclamation of Independence Day", | ||
"date": "2023-01-11" | ||
}, | ||
{ | ||
"name": "Amazigh New Year (\u2d49\u2d39 \u2d4f \u2d62\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54)", | ||
"date": "2023-01-14" | ||
}, | ||
{ | ||
"name": "Eid al-Fitr", | ||
"date": "2023-04-22" | ||
}, | ||
{ | ||
"name": "Eid al-Fitr 2", | ||
"date": "2023-04-23" | ||
}, | ||
{ | ||
"name": "Labour Day", | ||
"date": "2023-05-01" | ||
}, | ||
{ | ||
"name": "Eid al-Adha", | ||
"date": "2023-06-29" | ||
}, | ||
{ | ||
"name": "Eid al-Adha 2", | ||
"date": "2023-06-30" | ||
}, | ||
{ | ||
"name": "Islamic New Year", | ||
"date": "2023-07-19" | ||
}, | ||
{ | ||
"name": "Throne Day", | ||
"date": "2023-07-30" | ||
}, | ||
{ | ||
"name": "Oued Ed-Dahab Day", | ||
"date": "2023-08-14" | ||
}, | ||
{ | ||
"name": "Revolution Day", | ||
"date": "2023-08-20" | ||
}, | ||
{ | ||
"name": "Youth Day", | ||
"date": "2023-08-21" | ||
}, | ||
{ | ||
"name": "Birthday of the Prophet Muhammad", | ||
"date": "2023-09-27" | ||
}, | ||
{ | ||
"name": "Birthday of the Prophet Muhammad 2", | ||
"date": "2023-09-28" | ||
}, | ||
{ | ||
"name": "Green March", | ||
"date": "2023-11-06" | ||
}, | ||
{ | ||
"name": "Independence Day", | ||
"date": "2023-11-18" | ||
} | ||
] |
70 changes: 70 additions & 0 deletions
70
tests/.pest/snapshots/Countries/MoroccoTest/it_can_calculate_morocco_holidays_2024.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
[ | ||
{ | ||
"name": "New Year's Day", | ||
"date": "2024-01-01" | ||
}, | ||
{ | ||
"name": "Proclamation of Independence Day", | ||
"date": "2024-01-11" | ||
}, | ||
{ | ||
"name": "Amazigh New Year (\u2d49\u2d39 \u2d4f \u2d62\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54)", | ||
"date": "2024-01-14" | ||
}, | ||
{ | ||
"name": "Eid al-Fitr", | ||
"date": "2024-04-10" | ||
}, | ||
{ | ||
"name": "Eid al-Fitr 2", | ||
"date": "2024-04-11" | ||
}, | ||
{ | ||
"name": "Labour Day", | ||
"date": "2024-05-01" | ||
}, | ||
{ | ||
"name": "Eid al-Adha", | ||
"date": "2024-06-17" | ||
}, | ||
{ | ||
"name": "Eid al-Adha 2", | ||
"date": "2024-06-18" | ||
}, | ||
{ | ||
"name": "Islamic New Year", | ||
"date": "2024-07-08" | ||
}, | ||
{ | ||
"name": "Throne Day", | ||
"date": "2024-07-30" | ||
}, | ||
{ | ||
"name": "Oued Ed-Dahab Day", | ||
"date": "2024-08-14" | ||
}, | ||
{ | ||
"name": "Revolution Day", | ||
"date": "2024-08-20" | ||
}, | ||
{ | ||
"name": "Youth Day", | ||
"date": "2024-08-21" | ||
}, | ||
{ | ||
"name": "Birthday of the Prophet Muhammad", | ||
"date": "2024-09-16" | ||
}, | ||
{ | ||
"name": "Birthday of the Prophet Muhammad 2", | ||
"date": "2024-09-17" | ||
}, | ||
{ | ||
"name": "Green March", | ||
"date": "2024-11-06" | ||
}, | ||
{ | ||
"name": "Independence Day", | ||
"date": "2024-11-18" | ||
} | ||
] |
70 changes: 70 additions & 0 deletions
70
tests/.pest/snapshots/Countries/MoroccoTest/it_can_calculate_morocco_holidays_2025.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
[ | ||
{ | ||
"name": "New Year's Day", | ||
"date": "2025-01-01" | ||
}, | ||
{ | ||
"name": "Proclamation of Independence Day", | ||
"date": "2025-01-11" | ||
}, | ||
{ | ||
"name": "Amazigh New Year (\u2d49\u2d39 \u2d4f \u2d62\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54)", | ||
"date": "2025-01-14" | ||
}, | ||
{ | ||
"name": "Eid al-Fitr", | ||
"date": "2025-03-31" | ||
}, | ||
{ | ||
"name": "Eid al-Fitr 2", | ||
"date": "2025-04-01" | ||
}, | ||
{ | ||
"name": "Labour Day", | ||
"date": "2025-05-01" | ||
}, | ||
{ | ||
"name": "Eid al-Adha", | ||
"date": "2025-06-07" | ||
}, | ||
{ | ||
"name": "Eid al-Adha 2", | ||
"date": "2025-06-08" | ||
}, | ||
{ | ||
"name": "Islamic New Year", | ||
"date": "2025-06-27" | ||
}, | ||
{ | ||
"name": "Throne Day", | ||
"date": "2025-07-30" | ||
}, | ||
{ | ||
"name": "Oued Ed-Dahab Day", | ||
"date": "2025-08-14" | ||
}, | ||
{ | ||
"name": "Revolution Day", | ||
"date": "2025-08-20" | ||
}, | ||
{ | ||
"name": "Youth Day", | ||
"date": "2025-08-21" | ||
}, | ||
{ | ||
"name": "Birthday of the Prophet Muhammad", | ||
"date": "2025-09-05" | ||
}, | ||
{ | ||
"name": "Birthday of the Prophet Muhammad 2", | ||
"date": "2025-09-06" | ||
}, | ||
{ | ||
"name": "Green March", | ||
"date": "2025-11-06" | ||
}, | ||
{ | ||
"name": "Independence Day", | ||
"date": "2025-11-18" | ||
} | ||
] |
Oops, something went wrong.