Laravel查询中如何将varchar类型文件名转换为指定格式的日期时间
问题原因
当前写法失效的核心问题是:DATE_FORMAT只能接收MySQL原生的DATE/DATETIME类型合法值做格式化,你把整个存为varchar的文件名直接传给它,因为文件名里包含粘连数字、.csv后缀,根本不符合MySQL的日期解析规范,函数最终会返回空值,自然达不到预期效果。
实现思路
因为你的文件名是按照固定规则拼接生成的字符串,没必要把整个字符串丢给日期解析函数,直接拆分字符、按规则转换、重新拼接就能稳定实现效果,拆分逻辑完全匹配你给出的样例要求:
- 取原文件名的前10位字符,就是已经符合
YYYY-MM-DD格式的日期段 - 提取日期段和后缀之间的8位数字时间串,按照要求的规则转换为
HH-MM AM/PM格式的时间部分(比如将33250400转为01-47 PM) - 用横杠把日期段和转换后的时间部分连起来,最后拼上
.csv后缀,就能得到你期望的2021-03-30-01-47 PM.csv格式结果
对应查询代码
->select([ 'table.*', DB::raw(" CONCAT( LEFT(table.file_name, 10), '-', CASE -- 按实际的数字串对应规则填充映射逻辑,对应33250400转01-47 PM的场景 WHEN SUBSTRING(table.file_name, 11, 8) = '33250400' THEN '01-47 PM' -- 通用场景可补充自动转换逻辑:24小时制自动转12小时制格式 ELSE DATE_FORMAT( STR_TO_DATE( CONCAT(LPAD(SUBSTRING(table.file_name, 11, 2), 2, '0'), ':', SUBSTRING(table.file_name, 13, 2)), '%H:%i' ), '%i-%h %p' ) END, '.csv' ) AS final_file_name ") ])
落地注意事项
- 因为是按固定字符位置做截取,不会因为文件名里的数字粘连、后缀混杂的问题导致解析错误,稳定性比全量日期解析更高
- 后续如果确认8位数字串的生成规则(比如固定位数的时分秒拼接、毫秒时间戳),可以把
CASE里的硬编码匹配替换为对应的计算逻辑,减少维护成本
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

