Laravel中用Carbon筛选MySQL60天前数据并格式化日期
解决Laravel中筛选60天前数据并格式化日期的问题
嘿,我来帮你搞定这个需求!你的现有代码里有几个关键问题需要调整,同时我会帮你实现日期格式化的目标:
原代码的问题
- 你用了
=来匹配requested_at和60天前的时间,这只会拿到恰好是60天前此刻的记录,而不是所有早于60天的记录,应该用<来做比较。 Carbon::now()->subDays(60)会直接修改$now这个Carbon实例(Carbon的链式方法默认是修改原对象的),如果之后还要用$now的话会出问题,最好直接链式调用或者用copy()方法避免污染原实例。
正确的实现方案
下面提供两种常用的实现方式,你可以根据自己的场景选择:
方案1:直接用查询构建器(数据库层面格式化)
这种方式直接在SQL查询里把日期转成YYYY-MM-DD格式,返回结果里直接带格式化后的字段:
// 直接生成60天前的时间,不用存到$now变量避免后续问题 $records = DB::table('exampletable') // 格式化requested_at为年月日,别名formatted_date ->select(DB::raw('DATE(requested_at) as formatted_date'), '*') // 筛选早于60天前的所有记录 ->where('requested_at', '<', Carbon::now()->subDays(60)) ->get();
如果你只想比较日期部分(不管具体时间,比如只要是60天前及更早的日期就符合条件),可以用whereDate方法:
$records = DB::table('exampletable') ->select(DB::raw('DATE(requested_at) as formatted_date'), '*') ->whereDate('requested_at', '<', Carbon::now()->subDays(60)->toDateString()) ->get();
方案2:用Eloquent模型+访问器(应用层面格式化)
如果你有对应的Eloquent模型(比如ExampleModel),可以通过定义访问器来自动格式化日期,这样后续使用起来更灵活:
首先在模型里添加访问器:
class ExampleModel extends Model { protected $table = 'exampletable'; // 开启时间戳自动转换(Laravel默认开启,确保这个属性存在) protected $dates = ['requested_at']; // 定义访问器,自动生成格式化后的日期字段 public function getFormattedRequestedAtAttribute() { return $this->requested_at->format('Y-m-d'); } }
然后查询的时候就不用管格式化,直接获取即可:
$records = ExampleModel::where('requested_at', '<', Carbon::now()->subDays(60))->get(); // 每个record都可以通过formatted_requested_at拿到格式化后的日期 foreach ($records as $record) { echo $record->formatted_requested_at; // 输出类似2018-02-03 }
内容的提问来源于stack exchange,提问作者Trayer
相关产品推荐
相关产品推荐

