PHP Carbon如何忽略秒数按分钟精度比对Datetime时间
解决方案
下面是几种可直接落地的实现方式:
方案1:时间范围查询(性能最优,推荐)
取当前分钟的开始和结束时间作为查询区间,可复用completed_at字段的索引,适配所有类型的数据库,数据量大时也不会出现性能问题:
$startOfMinute = now()->startOfMinute(); $endOfMinute = now()->endOfMinute(); $bookings = Booking::whereBetween('completed_at', [$startOfMinute, $endOfMinute])->get();
方案2:分钟级格式化比对
如果业务数据量小,也可以直接将时间统一格式化为分钟级字符串后比对:
- MySQL环境写法:
$bookings = Booking::whereRaw("DATE_FORMAT(completed_at, '%Y-%m-%d %H:%i') = ?", [now()->format('Y-m-d H:i')])->get();
- PostgreSQL环境写法:
$bookings = Booking::whereRaw("TO_CHAR(completed_at, 'YYYY-MM-DD HH24:MI') = ?", [now()->format('Y-m-d H:i')])->get();
注意:该方案会导致
completed_at字段的索引失效,单表数据超过10万条时不建议使用。
问题原因说明
你原先的写法Booking::where('completed_at', now())->get()是精确到秒做时间比对,cronjob每分钟执行一次的触发时间的秒数,不可能和所有预约完成时间的秒数完全匹配,自然会漏查数据,调整为分钟级精度的比对逻辑后即可覆盖同一分钟内所有完成的预约记录。
内容的提问来源于stack exchange,提问作者Prem Arumugam
相关产品推荐
相关产品推荐

