Laravel 7 如何结合数值加减实现分半天的日期差计算
带半天拆分的日期间隔计算实现
核心逻辑
需求本质是把单日拆分为上、下两个0.5天的统计单元,计算时需要把起止日期选中的半天偏移量纳入计算,不能直接用Carbon默认的diff()方法取间隔——默认方法仅计算两个时间点的自然时间差,不会处理首尾半天的统计权重。
首先明确时段和偏移值的对应关系:
- 开始日期选上半天:对应偏移值
0 - 开始日期选下半天:对应偏移值
0.5 - 结束日期选上半天:对应偏移值
0.5 - 结束日期选下半天:对应偏移值
0
计算总天数的公式为:
总天数 = (两个日期的自然整天差 + 1) - 开始日期偏移 - 结束日期偏移
公式验证(以2022-06-28到2022-06-29为例,自然整天差为1):
- 28日上半天 → 29日下半天:(1+1) - 0 - 0 = 2天,符合需求
- 28日上半天 → 29日上半天:(1+1) -0 -0.5 =1.5天,符合需求
- 28日下半天 → 29日下半天:(1+1) -0.5 -0 =1.5天,和示例计算结果一致
- 28日下半天 → 29日上半天:(1+1) -0.5 -0.5 =1天,和示例计算结果一致
完整实现代码
// 读取参数,提前做好值映射,不要直接使用未校验的请求参数 $startHalf = $request->session_2; // 上半天传0,下半天传0.5 $endHalf = $request->session_1; // 上半天传0.5,下半天传0 $start = Carbon::parse($request->start_date)->startOfDay(); $end = Carbon::parse($request->end_date)->startOfDay(); // 基础参数合法性校验 if ($end->lt($start)) { // 可按业务需求调整处理逻辑:返回错误、交换日期顺序均可 throw new \InvalidArgumentException('结束日期不能早于开始日期'); } if (!in_array($startHalf, [0, 0.5]) || !in_array($endHalf, [0, 0.5])) { throw new \InvalidArgumentException('半天时段参数非法'); } // 计算最终总天数 $dayDiff = $end->diffInDays($start); $totalDays = ($dayDiff + 1) - $startHalf - $endHalf;
额外说明
- 解析日期时调用
startOfDay()是为了屏蔽传入日期自带的时分秒参数干扰,保证自然日差计算准确 - 公式同样支持同一天的场景计算:比如选28日上半天到28日下半天,自然天差为0,计算得(0+1)-0-0=1天,符合全天统计结果;选28日上半天到28日上半天,计算得(0+1)-0-0.5=0.5天,符合单半天统计结果。
内容的提问来源于stack exchange,提问作者Shan Md Shazarul Haque 171-15-
相关产品推荐
相关产品推荐

