Laravel中如何对两个time类型的数据执行加法运算?
解决方案
问题原因
原写法错误原因:strtotime()处理00:30:00这类纯时间格式时,会默认将其识别为当前时区下当日的对应时间,两个时间戳都携带了时区偏移量,相加后会额外叠加两倍时区偏移,最终结果出错。
最优方案:使用Laravel Carbon实现
Laravel自带的Carbon库可以完美解决这个问题,全程指定UTC时区计算即可彻底规避时区偏移影响:
写法1:通过CarbonInterval直接解析时长(最简洁)
use Carbon\Carbon; use Carbon\CarbonInterval; // 以UTC时区解析起始时间,避免时区偏移 $startTime = Carbon::parse($booking_service->start_time, 'UTC'); // 解析duration为时间间隔 $duration = CarbonInterval::createFromFormat('H:i:s', $service->duration); // 相加后格式化为time类型需要的H:i:s格式 $booking_service->end_time = $startTime->add($duration)->format('H:i:s'); // 保存数据 $booking_service->save();
写法2:拆分时长手动累加(兼容性更好)
如果duration可能存在非标准格式,用拆分的方式更稳妥:
use Carbon\Carbon; $startTime = Carbon::parse($booking_service->start_time, 'UTC'); list($hours, $minutes, $seconds) = explode(':', $service->duration); $endTime = $startTime->copy()->addHours($hours)->addMinutes($minutes)->addSeconds($seconds); $booking_service->end_time = $endTime->format('H:i:s'); $booking_service->save();
纯PHP无依赖实现方案
如果不想依赖Carbon,也可以直接通过秒数转换实现,全程不涉及时区逻辑,不会产生偏移:
// 自定义时间转秒数方法 function timeToTotalSeconds(string $time): int { list($hours, $minutes, $seconds) = array_map('intval', explode(':', $time)); return $hours * 3600 + $minutes * 60 + $seconds; } // 自定义秒数转H:i:s方法,支持超过24小时的时长 function totalSecondsToTime(int $seconds): string { $hours = floor($seconds / 3600); $minutes = floor(($seconds % 3600) / 60); $remainingSeconds = $seconds % 60; return sprintf('%02d:%02d:%02d', $hours, $minutes, $remainingSeconds); } // 计算逻辑 $totalSeconds = timeToTotalSeconds($booking_service->start_time) + timeToTotalSeconds($service->duration); $booking_service->end_time = totalSecondsToTime($totalSeconds); $booking_service->save();
内容的提问来源于stack exchange,提问作者Mohammadreza Sahelgozin
相关产品推荐
相关产品推荐

