Laravel下当日学生注册数统计为0,其余周期统计正常的问题求助
当日学生注册数统计显示为0的问题排查与修复
问题描述
我需要统计当日、过去7天、15天、30天、6个月及1年的学生注册数量,其余周期的统计结果均符合预期,但当日注册数始终显示为0,且无报错信息。
相关代码
$registration_summery = [ 'Registrations today' => '+0 days', 'Registrations in the last 7 Days' => '-7 days', 'Registrations in the last 15 Days' => '-15 days', 'Registrations in the last 30 Days' => '-30 days', 'Registrations in the last 6 month' => '-6 months', 'Registrations in the last 1 year' => '-1 Years' ]; $toReturn['registration_summery'][] = ['name' => 'Total Learners', 'value' => \DB::table('users')->where('users.role', 'student')->count()]; foreach ($registration_summery as $key => $value) { $tmp = \DB::table('users')->where('role', 'student') ->where('createdAt', '>=', strtotime("tomorrow", strtotime($value)) - 1) ->where('createdAt', '<=', strtotime("midnight")) ->count(); $toReturn['registration_summery'][] = ['name' => $key, 'value' => $tmp]; }
问题原因分析
咱们直接看当日统计的时间逻辑:当$value是'+0 days'时,strtotime("tomorrow", strtotime($value))会算出明天当前时间,减1秒后还是远大于今天的凌晨0点(strtotime("midnight"))。这就导致查询条件变成了createdAt >= 明天的某个时间且createdAt <= 今天凌晨——这是一个完全不存在的空区间,结果自然是0。
另外,其他周期的逻辑其实也有隐患:比如-7 days对应的strtotime("tomorrow", strtotime("-7 days"))是7天前的明天,这和你想要的"过去7天(从7天前到今天)"的范围不符,只是刚好可能因为数据时间的问题返回了看似正确的结果。
修复方案
我们重新定义每个周期的正确时间范围,同时简化逻辑避免出错:
- 当日:从今天凌晨0点到当前时间
- 过去N天/月/年:从指定时间点到当前时间
修改后的代码如下:
$registration_summery = [ 'Registrations today' => 'today', 'Registrations in the last 7 Days' => '-7 days', 'Registrations in the last 15 Days' => '-15 days', 'Registrations in the last 30 Days' => '-30 days', 'Registrations in the last 6 month' => '-6 months', 'Registrations in the last 1 year' => '-1 year' ]; $toReturn['registration_summery'][] = ['name' => 'Total Learners', 'value' => \DB::table('users')->where('users.role', 'student')->count()]; foreach ($registration_summery as $key => $value) { $startTime = $value === 'today' ? strtotime('today') : strtotime($value); $endTime = time(); // 当前时间,确保统计到最新数据 $tmp = \DB::table('users')->where('role', 'student') ->where('createdAt', '>=', $startTime) ->where('createdAt', '<=', $endTime) ->count(); $toReturn['registration_summery'][] = ['name' => $key, 'value' => $tmp]; }
进阶优化建议
如果你的createdAt字段存储的是DateTime格式(而非时间戳),可以改用Laravel自带的时间查询方法,更直观且不易出错:
// 当日统计示例 ->whereDate('createdAt', today()) // 过去7天统计示例 ->whereDate('createdAt', '>=', now()->subDays(7)) // 过去6个月统计示例 ->whereDate('createdAt', '>=', now()->subMonths(6))
内容的提问来源于stack exchange,提问作者Keerthi Dsouza
相关产品推荐
相关产品推荐

