如何在自定义时间戳expire_at上使用diffForHumans?附报错解决
解决Laravel中Carbon diffForHumans() 报错“A two digit month could not be found”
兄弟,我来帮你搞定这个棘手的报错!先给你拆解问题根源,再一步步给你修正方案:
问题根源分析
你遇到的这个报错,本质是Carbon无法正确解析你的expire_at字段值,大概率是两个原因:
- 你用
date()+strtotime()的组合生成日期时,可能因为$currentdate格式不标准,导致strtotime解析出了无效的日期,最终传给Carbon的是一个格式错误的字符串; - 你的
Subscription模型没有把expire_at字段声明为日期类型,导致从数据库取出的是普通字符串,而不是Carbon实例,直接调用diffForHumans()自然会出错。
分步解决方法
1. 简化日期生成逻辑,用Carbon替代date()+strtotime()
你的代码里绕了个没必要的弯,直接用Carbon处理日期更可靠,完全不需要date()和strtotime():
// 如果$currentdate是当前时间,直接这么写 $expire_at = Carbon::now()->addDays(30); // 如果$currentdate是从其他地方拿到的日期字符串(比如数据库或请求参数),先转Carbon再加天数 // $expire_at = Carbon::parse($currentdate)->addDays(30);
2. 确保模型将expire_at转为Carbon实例
打开你的Subscription模型,添加$casts属性,把expire_at字段声明为日期类型:
class Subscription extends Model { protected $casts = [ 'expire_at' => 'datetime', // 关键!让Laravel自动把字段转为Carbon实例 // 其他字段的cast如果有也可以加上 ]; }
3. 修正控制器的查询逻辑
你原来用get()然后取$data[0]的写法不够严谨,改用first()更安全(避免查询不到数据时报错):
// 替换原来的查询代码 $subscription = Subscription::where('email', $userEmail)->first(); // 一定要判断是否查询到数据,避免空指针错误 if ($subscription) { $subscription->expire_at = $expire_at; $subscription->save(); }
4. 视图里的正确调用
经过上面的设置,视图里直接调用diffForHumans()就没问题了:
<td>{{ $Data1->expire_at->diffForHumans() }}</td>
额外排查技巧
如果还是报错,你可以先在控制器里打印一下$expire_at的值,确认它是一个有效的Carbon实例,而不是奇怪的字符串:
dd($expire_at); // 输出应该是类似Carbon\Carbon @1699999999 {#xxx ...} 的格式
内容的提问来源于stack exchange,提问作者laravel porject
相关产品推荐
相关产品推荐

