You're right, Carbon's diffInWeekdays()
only returns an integer, and that's by design. It counts full weekdays between two dates, without considering partial days.
To handle half-days while excluding weekends and still return a float, you could manually filter and count the weekdays, applying 0.5 multipliers based on the start and end parts. Here's a practical approach:
$period = CarbonPeriod::create($startDate, $endDate);
$dayCount = 0;
foreach ($period as $date) {
if ($date->isWeekday()) {
if ($date->equalTo($startDate)) {
$dayCount += ($validated['leave_start_day_part'] == 'PM') ? 0.5 : 1;
} elseif ($date->equalTo($endDate)) {
$dayCount += ($validated['leave_end_day_part'] == 'AM') ? 0.5 : 1;
} else {
$dayCount += 1;
}
}
}
This way, full weekdays are counted as 1, and if your leave starts or ends with a half-day, it counts 0.5 accordingly. No weekends included, and the result stays a float, perfect for precise leave management systems.
In a similar project where I was tracking work sessions with a focus on accurate time logging, I found it super useful to cross-check day fractions using an hours calculator during testing. It helped avoid rounding errors in larger date ranges.
Regards,
Alex Bhatti