diff --git a/composer.json b/composer.json index 46ef42ee3..7014181f2 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,10 @@ ], "require": { "php": "^8.1", + "ext-calendar": "*", "ext-intl": "*", - "nesbot/carbon": "^2.72.1|^3.0" + "nesbot/carbon": "^2.72.1|^3.0", + "geniusts/hijri-dates": "^1.1" }, "require-dev": { "laravel/pint": "^1.0", diff --git a/src/Countries/Algeria.php b/src/Countries/Algeria.php new file mode 100644 index 000000000..1a92164f8 --- /dev/null +++ b/src/Countries/Algeria.php @@ -0,0 +1,123 @@ +fixedHolidays($year), $this->variableHolidays($year)); + } + + /** @return array */ + protected function fixedHolidays(int $year): array + { + return [ + 'New Year\'s Day' => CarbonImmutable::createFromDate($year, 1, 1), + 'Amazigh New Year' => CarbonImmutable::createFromDate($year, 1, 12), + 'Labour day' => CarbonImmutable::createFromDate($year, 5, 1), + 'Independence day' => CarbonImmutable::createFromDate($year, 7, 5), + 'Revolution Day' => CarbonImmutable::createFromDate($year, 11, 1), + ]; + } + + /** @return array */ + protected function variableHolidays(int $year): array + { + return [ + 'Islamic new year' => $this->getHijriDateAsGregorian(1, 1, $year + 1), + 'Ashura' => $this->getHijriDateAsGregorian(10, 1, $year + 1), + 'Mawlid' => $this->getHijriDateAsGregorian(12, 3, $year + 1), + 'Eid al-Fitr' => $this->getHijriDateAsGregorian(1, 10, $year, $this->adjustmentDays), + 'Eid al-Fitr - 2nd day' => $this->getHijriDateAsGregorian(2, 10, $year, $this->adjustmentDays), + 'Eid al-Adha' => $this->getHijriDateAsGregorian(10, 12, $year, $this->adjustmentDays), + 'Eid al-Adha - 2nd day' => $this->getHijriDateAsGregorian(11, 12, $year, $this->adjustmentDays), + 'Eid al-Adha - 3rd day' => $this->getHijriDateAsGregorian(12, 12, $year, $this->adjustmentDays), + ]; + } + + /** + * @param int $year + * @return int + */ + protected function convertToHijriYear(int $year): int + { + $gregorianNewYear = CarbonImmutable::create($year, 1, 1); + $hijriNewYear = Hijri::convertToHijri($gregorianNewYear); + $hijriYear = $hijriNewYear->year; + + return $hijriYear; + } + + /** + * Converts a Hijri date to a Gregorian date with a possible adjustment. + * + * @param int $hijriDay + * @param int $hijriMonth + * @param int $hijriYear + * @param int $adjustmentDays Number of days to adjust the Hijri date by. + * @return CarbonImmutable + */ + protected function getHijriDateAsGregorian(int $hijriDay, int $hijriMonth, int $hijriYear, int $adjustmentDays = 0): CarbonImmutable + { + $hijriYear = $this->convertToHijriYear($hijriYear); + $gregorianDate = Hijri::convertToGregorian($hijriDay, $hijriMonth, $hijriYear); + return CarbonImmutable::instance($gregorianDate)->addDays($adjustmentDays); + } + + /** + * Calculates the last 10 days of Ramadan for a given year. + * + * @param int $year + * @return array + */ + protected function getLastTenDaysOfRamadan(int $year): array + { + $last10DaysOfRamadan = []; + + $eidAlFitr = $this->getHijriDateAsGregorian(1, 10, $year, $this->adjustmentDays); // Shawwal 1 + + for ($i = 9; $i >= 0; $i--) { + $day = $eidAlFitr->subDays($i + 1); // Counting back from the day before Eid al-Fitr + $last10DaysOfRamadan["Last 10 Days of Ramadan - Day " . (10 - $i)] = $day; + } + return $last10DaysOfRamadan; + } + + /** + * Calculates the length of Ramadan for a given year. + * + * @param int $year + * @return int + */ + protected function getLengthOfRamadan(int $year): int + { + $firstDayOfRamadan = $this->getHijriDateAsGregorian(1, 9, $year); // Ramadan 1 + $lastDayOfRamadan = $this->getHijriDateAsGregorian(1, 10, $year); // Shawwal 1 + $lengthOfRamadan = $firstDayOfRamadan->diffInDays($lastDayOfRamadan); + return $lengthOfRamadan; + } + + /** + * Get the two days following an Eid day. + * + * @param CarbonImmutable $eidDay + * @return array + */ + protected function getDaysFollowingEid(CarbonImmutable $eidDay): array + { + $secondDay = $eidDay->addDay(); + $thirdDay = $eidDay->addDays(2); + return [$secondDay, $thirdDay]; + } +} diff --git a/tests/.pest/snapshots/Countries/AlgeriaTest/it_can_calculate_algerian_holidays.snap b/tests/.pest/snapshots/Countries/AlgeriaTest/it_can_calculate_algerian_holidays.snap new file mode 100644 index 000000000..e6783861b --- /dev/null +++ b/tests/.pest/snapshots/Countries/AlgeriaTest/it_can_calculate_algerian_holidays.snap @@ -0,0 +1,54 @@ +[ + { + "name": "New Year's Day", + "date": "2024-01-01" + }, + { + "name": "Amazigh New Year", + "date": "2024-01-12" + }, + { + "name": "Eid al-Fitr", + "date": "2024-04-10" + }, + { + "name": "Eid al-Fitr - 2nd day", + "date": "2024-04-11" + }, + { + "name": "Labour day", + "date": "2024-05-01" + }, + { + "name": "Eid al-Adha", + "date": "2024-06-17" + }, + { + "name": "Eid al-Adha - 2nd day", + "date": "2024-06-18" + }, + { + "name": "Eid al-Adha - 3rd day", + "date": "2024-06-19" + }, + { + "name": "Independence day", + "date": "2024-07-05" + }, + { + "name": "Islamic new year", + "date": "2024-07-07" + }, + { + "name": "Ashura", + "date": "2024-07-16" + }, + { + "name": "Mawlid", + "date": "2024-09-15" + }, + { + "name": "Revolution Day", + "date": "2024-11-01" + } +] \ No newline at end of file diff --git a/tests/Countries/AlgeriaTest.php b/tests/Countries/AlgeriaTest.php new file mode 100644 index 000000000..82f3b8cbf --- /dev/null +++ b/tests/Countries/AlgeriaTest.php @@ -0,0 +1,18 @@ +get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +});