startOfMonth(); $end = $start->copy()->endOfMonth(); return self::getWorkingDaysInRange($start->toDateString(), $end->toDateString(), $holidays); } public static function getWorkingDaysInRange(string $start, string $end, array $holidays = []): int { $period = CarbonPeriod::create( Carbon::create($start, self::TIMEZONE), Carbon::create($end, self::TIMEZONE) ); $holidayLookup = array_flip($holidays); $workingDays = 0; foreach ($period as $day) { $date = $day->toDateString(); if (self::isWorkingDay($date, $holidayLookup)) { $workingDays++; } } return $workingDays; } public static function isWorkingDay(string $date, array $holidays = []): bool { $carbonDate = Carbon::create($date, self::TIMEZONE); if ($carbonDate->isWeekend()) { return false; } if (isset($holidays[$carbonDate->toDateString()])) { return false; } return true; } public static function isWeekend(string $date): bool { return Carbon::create($date, self::TIMEZONE)->isWeekend(); } }