如何在Laravel中计算工时表多计时器的累计总时长
问题根源
你当前的实现存在两个核心错误:
$this->timers->sum('total')得到的是总分钟数,而date()函数的第二个参数要求传入Unix时间戳(单位为秒),单位不匹配导致计算结果完全错误- 你使用了
i:s格式,输出的是「分钟:秒」,不符合你需要的「小时:分钟」展示需求,且i的取值范围仅为0-59,总分钟数超过60时会自动进位隐藏真实累计小时数
修复方案
直接修改TsTask模型中的getTotalAttribute访问器即可,代码如下:
public function getTotalAttribute() { // 统计所有关联计时器的总分钟数 $totalMinutes = $this->timers->sum('total'); // 拆分得到小时和剩余分钟 $hours = floor($totalMinutes / 60); $minutes = $totalMinutes % 60; // 格式化输出,分钟不足2位自动补0,最终效果如 5:10、01:05 return sprintf('%d:%02d', $hours, $minutes); }
如果需要小时也固定为2位(比如不足10小时前补0,展示为05:10),将格式化字符串改为'%02d:%02d'即可。
可选优化建议
- 如果你需要统计仍在运行中(
end字段为null)的计时器时长,可调整求和逻辑:
public function getTotalAttribute() { $totalMinutes = $this->timers->sum(function ($timer) { if ($timer->end) { return $timer->total; } // 未结束的计时器计算从开始时间到当前时间的分钟数 return $timer->start->diffInMinutes(now()); }); $hours = floor($totalMinutes / 60); $minutes = $totalMinutes % 60; return sprintf('%d:%02d', $hours, $minutes); }
- 批量查询任务列表时建议预加载
timers关联,避免出现N+1性能问题:
// 预加载关联的写法 $tasks = TsTask::with('timers')->get();
内容的提问来源于stack exchange,提问作者Omar Alsayed Ahmad
相关产品推荐
相关产品推荐

