Пересечение двух диапазонов дат получить довольно просто - это разница между самым поздним началом и самым ранним концом этих периодов.
/**
* Предполагается, что dateStart <= dateEnd. Если это не гарантируется, нужно их привести к такому виду внутри функции.
*/
function getIntersectDays(DateTime $dateStart1, DateTime $dateEnd1, DateTime $dateStart2, DateTime $dateEnd2) : int {
$intersectionEnd = min($dateEnd1, $dateEnd2);
$intersectionStart = max($dateStart1, $dateStart2);
if ($intersectionStart >= $intersectionEnd) return 0;
return (int)$intersectionStart->diff($intersectionEnd)->format('%a');
}