You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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-

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:27:13