验证数据库日期格式正确性 修复Carbon日期解析报错问题
问题描述
需要验证数据库中日期字段的格式是否正确,添加校验逻辑,若格式错误则存储空值。当前使用Laravel框架结合Carbon组件编写的校验代码无法正常工作,未添加校验时,遇到错误格式的日期会触发「Unexpected data found. Data missing」错误,现有代码片段如下:
$getTmpAfSite = DB::table('tmp_af_site')->orderBy('id','DESC')->get(['id','name','email','number','origin','destination','estimated_rate','make','model','year','running_condition','carrier_type','avail_date','lead_source','request_params','bats_id','submitted_on']); foreach ($getTmpAfSite as $key => $value) { $avail_date = ($value->avail_date != '' && $value->avail_date == Carbon::parse($value->submitted_on)->format('m/d/Y')) ? Carbon::createFromFormat('m/d/Y', $value->avail_date)->format('Y-m-d') : '0000-00-00'; $submitted_on = ($value->submitted_on != '' && $value->submitted_on == Carbon::parse($value->submitted_on)->format('m/d/Y H:i')) ? Carbon::createFromFormat('m/d/Y H:i', $value->submitted_on)->format('Y-m-d H:i') : '0000-00-00 00:00:00'; DB::table('tmp_af_site')->where('id', $value->id)->update([ 'avail_date'=>$avail_date, 'submitted_on'=>$submitted_on ]); }
解决方案
核心问题是原代码用Carbon::parse()自动解析后再对比格式的逻辑完全不可靠,而且没有处理解析失败的异常。以下是修复方案:
- 用异常捕获判断格式合法性:直接用
Carbon::createFromFormat()按目标格式解析,捕获InvalidFormatException异常来识别格式错误 - 优先用
NULL存储无效日期:0000-00-00是SQL非标准的无效日期,建议改为存储NULL(需确保数据库字段允许为空) - 处理字段前后空格:添加
trim()避免因字段首尾空格导致的解析失败
修正后的代码
use Carbon\Carbon; use Carbon\Exceptions\InvalidFormatException; $getTmpAfSite = DB::table('tmp_af_site') ->orderBy('id', 'DESC') ->get(['id', 'name', 'email', 'number', 'origin', 'destination', 'estimated_rate', 'make', 'model', 'year', 'running_condition', 'carrier_type', 'avail_date', 'lead_source', 'request_params', 'bats_id', 'submitted_on']); foreach ($getTmpAfSite as $value) { // 处理avail_date字段 $availDate = null; if (!empty(trim($value->avail_date))) { try { $availDate = Carbon::createFromFormat('m/d/Y', trim($value->avail_date))->format('Y-m-d'); } catch (InvalidFormatException $e) { // 格式错误,保持null } } // 处理submitted_on字段 $submittedOn = null; if (!empty(trim($value->submitted_on))) { try { $submittedOn = Carbon::createFromFormat('m/d/Y H:i', trim($value->submitted_on))->format('Y-m-d H:i:s'); } catch (InvalidFormatException $e) { // 格式错误,保持null } } DB::table('tmp_af_site')->where('id', $value->id)->update([ 'avail_date' => $availDate, 'submitted_on' => $submittedOn ]); }
补充说明
- 原代码中用
Carbon::parse($value->submitted_on)->format(...)和原字段对比的逻辑错误:parse()会自动识别多种日期格式,哪怕原格式不符合要求也可能返回一个格式化后的结果,导致判断完全失效 - 如果业务必须要用
0000-00-00这类值,只需把代码中的null替换成'0000-00-00'(对应submitted_on替换成'0000-00-00 00:00:00')即可,但不推荐这种做法 - 可以进一步优化为批量更新,减少数据库交互次数,比如收集所有需要更新的数据后一次性执行
update()
内容的提问来源于stack exchange,提问作者jamie liam
相关产品推荐
相关产品推荐

