
本文讲解如何将 jquery datepicker 返回的“07/29/2022 - 07/30/2022”格式日期范围字符串安全拆解、校验并转换为标准日期格式(如 'y-m-d'),再存入 laravel 数据库的 timestamp 或 date 字段。
本文讲解如何将 jquery datepicker 返回的“07/29/2022 - 07/30/2022”格式日期范围字符串安全拆解、校验并转换为标准日期格式(如 'y-m-d'),再存入 laravel 数据库的 timestamp 或 date 字段。
在使用 jQuery Datepicker(尤其是双日期范围选择器)时,常见做法是将起止日期合并为单个输入字段的值,例如 07/29/2022 - 07/30/2022。但该字符串无法直接用于数据库存储——Laravel 的 starts_at 字段通常为 datetime 或 date 类型,需转换为标准 ISO 格式(如 2022-07-29)。原始代码中错误地嵌套使用 Carbon::parse() 与 Carbon::createFromFormat(),导致解析失败:Trailing data 错误表明 Carbon 在解析时遇到了无法识别的多余字符(如空格、短横线或格式不匹配)。
✅ 正确解析步骤
首先,安全拆分字符串,避免因空格导致解析异常:
$daterange = $request->input('datepicker'); // e.g. "07/29/2022 - 07/30/2022"
$dates = array_map('trim', explode('-', $daterange)); // → ['07/29/2022', '07/30/2022']
array_map('trim', ...) 至关重要——它清除两端空格,否则 07/29/2022␣(含尾随空格)会触发 Trailing data 错误。
接着,使用 createFromFormat() 精确解析(而非 parse()),指定输入格式 'm/d/Y':
$startsAt = Carbon::createFromFormat('m/d/Y', $dates[0])->format('Y-m-d'); // 注意:推荐 'Y-m-d' 而非 'y-m-d'
$endsAt = Carbon::createFromFormat('m/d/Y', $dates[1])->format('Y-m-d');
⚠️ 注意:'y-m-d' 表示两位年份(如 22-07-29),极易引发数据歧义和排序问题,务必使用 'Y-m-d'(四位年份),符合 MySQL DATE 类型要求及 Laravel 时间处理惯例。
? 必须添加输入验证
前端不可信,必须服务端校验格式合法性:
$request->validate([
'datepicker' => [
'required',
'string',
'regex:/^\d{1,2}\/\d{1,2}\/\d{4}\s*-\s*\d{1,2}\/\d{1,2}\/\d{4}$/'
]
]);
该正则确保输入严格匹配 M/D/YYYY - M/D/YYYY(允许短横线两侧有空格),防止注入无效字符串导致 Carbon 解析崩溃。
? 完整保存示例(Laravel Controller)
use Carbon\Carbon;
public function store(Request $request)
{
$request->validate([
'datepicker' => 'required|string|regex:/^\d{1,2}\/\d{1,2}\/\d{4}\s*-\s*\d{1,2}\/\d{1,2}\/\d{4}$/'
]);
$dates = array_map('trim', explode('-', $request->input('datepicker')));
$startsAt = Carbon::createFromFormat('m/d/Y', $dates[0])->format('Y-m-d');
$endsAt = Carbon::createFromFormat('m/d/Y', $dates[1])->format('Y-m-d');
YourModel::create([
'starts_at' => $startsAt,
'ends_at' => $endsAt,
// 其他字段...
]);
return redirect()->back()->with('success', '日期范围保存成功!');
}
? 总结要点
- ❌ 避免 Carbon::parse() 处理带分隔符的复合字符串;
- ✅ 用 explode() + array_map('trim') 安全拆分;
- ✅ createFromFormat() 明确指定输入格式,提升健壮性;
- ✅ 始终使用 'Y-m-d'(非 'y-m-d')保证年份无歧义;
- ✅ 强制服务端正则校验,杜绝非法输入进入解析流程。
遵循以上实践,即可稳定、安全地将 Datepicker 的范围字符串持久化到数据库。











