PHP Carbon diffInWeekdays替代方案:返回浮点数而非整数
解决方案:计算排除周末的带小数休假天数
Carbon的内置工作日统计方法(如diffInWeekdays、diffInDaysFiltered)仅返回整数,无法直接处理半天休假的浮点数需求。你可以通过拆分计算的方式实现,核心思路是分别统计完整工作日、开始当天、结束当天的休假时长,再合并结果:
实现代码
// 生成休假起始/结束时间(复用你的原有逻辑) if($validated['leave_start_day_part'] == 'AM'){ $startDate = Carbon::createFromDate($validated['leave_start_date'])->startOfDay(); }else{ $startDate = Carbon::createFromDate($validated['leave_start_date'])->midDay(); } if($validated['leave_end_day_part'] == 'AM'){ $endDate = Carbon::createFromDate($validated['leave_end_date'])->midDay(); }else{ $endDate = Carbon::createFromDate($validated['leave_end_date'])->endOfDay(); } $totalLeaveDays = 0.0; // 处理同一天休假的特殊情况 if ($startDate->isSameDay($endDate)) { if ($startDate->isWeekday()) { // 全天休假(上午到下午) if ($validated['leave_start_day_part'] == 'AM' && $validated['leave_end_day_part'] == 'PM') { $totalLeaveDays = 1.0; } else { // 半天休假 $totalLeaveDays = 0.5; } } // 周末休假不计入,直接返回0 return $totalLeaveDays; } // 计算中间的完整工作日天数(起始日次日到结束日前一日) $fullWorkdays = $startDate->copy()->addDay()->diffInWeekdays($endDate->copy()->subDay()); $totalLeaveDays += $fullWorkdays; // 处理起始当天的休假时长 if ($startDate->isWeekday()) { $totalLeaveDays += $validated['leave_start_day_part'] == 'AM' ? 1.0 : 0.5; } // 处理结束当天的休假时长 if ($endDate->isWeekday()) { $totalLeaveDays += $validated['leave_end_day_part'] == 'AM' ? 0.5 : 1.0; } // 最终结果示例:3.5、2.0、0.5等 echo $totalLeaveDays;
逻辑说明
- 同一天休假处理:如果起始和结束是同一天,直接根据时段判断是0.5天(仅上午/仅下午)还是1天(全天),周末则不计入。
- 完整工作日统计:用
diffInWeekdays计算起始日次日到结束日前一日的完整工作日数量,自动排除周末。 - 首尾天数单独计算:分别判断起始日、结束日是否为工作日,再根据时段(AM/PM)添加对应的0.5或1.0天。
这种方法既保留了浮点数的精度,又确保周末不会被计入休假配额。
内容的提问来源于stack exchange,提问作者PeteB
相关产品推荐
相关产品推荐

