会员到期时间加 30 天、统计最近 7 天的订单,这类活在 MySQL 里都归 date_add 管。语法一个套路:DATE_ADD(日期, INTERVAL 数值 单位),单位常用 DAY、HOUR、MINUTE、MONTH、YEAR。
SELECT DATE_ADD('2026-10-31', INTERVAL 1 DAY); -- 得 2026-11-01常用单位与写法
常见的几个:DATE_ADD(NOW(), INTERVAL 30 DAY) 是 30 天后;DATE_ADD(NOW(), INTERVAL -1 HOUR) 是 1 小时前;DATE_SUB(NOW(), INTERVAL 1 WEEK) 和负数写法等价,都是往前减,团队统一用一种就好。
单位写单复数都行,DAY 和 DAYS 都认。单位还能组合,比如 INTERVAL '1-2' DAY_HOUR 表示 1 天 2 小时,不过可读性一般,实际项目多数是单个单位加负号。传进去的日期可以是字符串、DATE、DATETIME,直接扔 NOW()、CURDATE() 也行,返回类型一般跟着参数走,拿不准就 SELECT 一下看结果。
业务里两个典型用法
UPDATE user SET expire_time = DATE_ADD(expire_time, INTERVAL 30 DAY) WHERE id = 1;会员到期时间延长 30 天,就这一行。
SELECT * FROM orders WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY);最近 7 天的订单,CURDATE 配 DATE_SUB 拿到 7 天前的零点,时间范围查法照搬。
容易翻车的地方
- 1 月 31 日加 1 个月会落到 2 月底,MySQL 自动取当月最后一天,跨数据库迁移时这个行为可能有差异
- 传非法日期比如 2 月 30 日,函数返回 NULL,严格模式下直接报错,数据插不进去
- 对日期列套了函数再去比较,索引一般用不上,大表按时间查时把函数写在常量那一侧
- NOW() 取的是服务器时区时间,跨时区业务别拿它当账期边界
还有个等价写法:日期直接加 INTERVAL,比如 create_time + INTERVAL 7 DAY,效果和 DATE_ADD 一样,看到别人这么写不用奇怪。