使用whereBetween无法获取数据库数据,日期区间查询返回空集合
嘿,我之前也踩过这个查询日期的坑!结合你的情况,大概率是这几个常见原因导致的,咱们一个个排查:
时区不一致问题
这是最容易忽略的点!如果你的应用框架(比如Laravel)时区和数据库时区不一样,存储的created_at实际是转成框架时区(比如UTC)存的,但你查询用的是本地时间,就会出现“明明有数据却查不到”的情况。
解决方法:要么统一应用和数据库的时区,要么查询时转换时区。举个例子,假设数据库是UTC,你要查北京时间的范围:$start = '2018-02-13 00:00:00'; $end = '2018-02-13 23:59:59'; $data = DB::table('your_table') ->whereBetween(DB::raw('CONVERT_TZ(created_at, "UTC", "Asia/Shanghai")'), [$start, $end]) ->get();或者直接把查询的日期转成UTC时间再传入:
$start = Carbon::parse('2018-02-13')->setTimezone('UTC'); $end = Carbon::parse('2018-02-13')->endOfDay()->setTimezone('UTC'); $data = YourModel::whereBetween('created_at', [$start, $end])->get();日期边界的时间范围问题
如果你查询的是['2018-02-13', '2018-02-13'],不带时间的话,框架会默认把结束时间解析为2018-02-13 00:00:00,而你的数据是13:33:41,自然不在这个区间里。
解决方法:把结束时间改成当天的最后一秒,或者用whereDate替代:// 方法1:指定结束时间为当天23:59:59 $data = YourModel::whereBetween('created_at', ['2018-02-13 00:00:00', '2018-02-13 23:59:59'])->get(); // 方法2:用whereDate直接匹配日期 $data = YourModel::whereDate('created_at', '=', '2018-02-13')->get(); // 方法3:用两个where条件明确范围 $data = YourModel::where('created_at', '>=', '2018-02-13') ->where('created_at', '<=', '2018-02-14') ->get();字段类型不匹配
确认一下你的created_at字段类型是DATETIME或TIMESTAMP,而不是DATE。如果是DATE类型,存储时会丢失时间部分,虽然你的数据显示有时间,但可能实际存储的是2018-02-13,这时候用带时间的范围查询也会出问题。可以直接在数据库里查看这条数据的实际存储值。Carbon对象的隐式时区转换
如果你用Carbon对象构建查询日期,要注意默认时区。比如Carbon::parse('2018-02-13')会用应用时区生成当天00:00:00的时间,如果数据库存储的是UTC时间,就会有偏差。这时候可以用endOfDay()来确保覆盖当天所有时间:$start = Carbon::parse('2018-02-13')->startOfDay(); $end = Carbon::parse('2018-02-13')->endOfDay(); $data = YourModel::whereBetween('created_at', [$start, $end])->get();
先试试这些方法,应该能解决你的问题!
内容的提问来源于stack exchange,提问作者PrStandup

