str_to_date()是mysql中将字符串转日期的唯一可靠函数,需严格匹配格式符与字符串结构,否则返回null;date()和cast()对非标准格式无效。

MySQL里用STR_TO_DATE()把字符串转成日期
直接用 STR_TO_DATE(),不是 DATE() 或 CAST() —— 后两者对非标准格式的字符串基本无效,容易返回 NULL 或 0000-00-00。
关键在第二个参数:它必须和字符串的实际格式**逐字符严格匹配**,哪怕多一个空格、少一个横线都会失败。
-
STR_TO_DATE('2023/05/12', '%Y/%m/%d')✅ -
STR_TO_DATE('2023-05-12', '%Y/%m/%d')❌(分隔符不一致) -
STR_TO_DATE('12-MAY-2023', '%d-%b-%Y')✅(注意%b是英文缩写,不是%M) -
STR_TO_DATE('20230512', '%Y%m%d')✅(无分隔符时不能加空格或斜杠)
常见错误:时间部分缺失或格式错位导致结果为NULL
MySQL默认把不完整的时间字符串补成 00:00:00,但前提是日期部分能被正确解析。一旦格式对不上,STR_TO_DATE() 直接返回 NULL,且不会报错——这很容易被忽略,查数据时发现一堆 NULL 才回头排查。
- 输入
'2023-5-1'却用'%Y-%m-%d'→ 失败(5不是两位数05) - 输入
'2023-05-12 14:30'却只写'%Y-%m-%d'→ 只取日期部分,时间丢弃,但不会报错 - 想保留时间就用
'%Y-%m-%d %H:%i',%H是24小时制,%h是12小时制,混用会解析失败
插入或更新时别忘了检查字段类型是否匹配
就算 STR_TO_DATE() 成功返回了日期值,如果目标字段是 DATE 类型,而你传入带时间的字符串(如 '2023-05-12 14:30:00'),MySQL 会自动截断时间部分;但如果目标是 DATETIME 或 TIMESTAMP,就必须保证格式里包含时间位,否则存进去是 2023-05-12 00:00:00。
- 往
DATE字段插:STR_TO_DATE('2023-05-12 14:30', '%Y-%m-%d')就够了 - 往
DATETIME字段插:STR_TO_DATE('2023-05-12 14:30', '%Y-%m-%d %H:%i')才能保留时间 - 如果源字符串是
'12/05/2023'(日/月/年),格式必须是'%d/%m/%Y',反了就是错的日期
批量处理前务必用SELECT验证转换逻辑
别急着写 UPDATE,先用 SELECT STR_TO_DATE(...) 查几条真实数据。尤其要注意数据里是否混杂多种格式(比如有的用横线、有的用斜杠、有的缺前导零),这种情况下单靠一个格式串搞不定,得先清洗或用 CASE WHEN 分条件处理。
- 执行
SELECT str_col, STR_TO_DATE(str_col, '%Y-%m-%d') FROM t WHERE str_col REGEXP '^[0-9]{4}-[0-9]{2}-[0-9]{2}$';看是否全成功 - 发现
NULL就说明有格式异常,用SELECT str_col FROM t WHERE STR_TO_DATE(str_col, '%Y-%m-%d') IS NULL;定位问题数据 - 别依赖客户端显示的“看起来像日期”的字符串——MySQL眼里只有格式匹配,不看人眼判断
最麻烦的其实是原始数据本身不规范,函数再准也没用。先看清数据长什么样,再选格式串,比反复试错快得多。











