last_day函数返回指定日期所在月份的最后一天,支持date、datetime及标准字符串输入,传入null返回null;常与curdate()配合获取当月月末,但需注意where中避免对字段使用该函数以防索引失效。

LAST_DAY 函数直接返回当月最后一天
LAST_DAY() 是 MySQL 内置日期函数,传入任意日期值(如 CURDATE()、NOW() 或字符串 '2024-03-15'),它会自动计算并返回该日期所在月份的最后一天,格式为 'YYYY-MM-DD'。不需要手动算天数、也不用判断闰年或大小月。
最常用写法就是:
SELECT LAST_DAY(CURDATE());结果类似
'2024-03-31'(取决于当前月份)。传入非当月日期也能正确计算
很多人误以为 LAST_DAY() 只能配合 CURDATE() 用,其实它对任意合法日期都有效。比如你想查去年 2 月最后一天:
SELECT LAST_DAY('2023-02-10'); -- 返回 '2023-02-28'再比如跨年场景:SELECT LAST_DAY('2024-02-01'); -- 返回 '2024-02-29'(闰年)
- 输入可以是
DATE、DATETIME或格式正确的字符串(如'2024-05'、'2024-05-01 10:30:00') - 如果传入
NULL,结果也是NULL,不会报错 - 不支持只传年份(如
'2024')或不完整格式(如'2024-05-'),会返回NULL并产生 warning
在 WHERE 条件中用 LAST_DAY 做范围查询要小心
想查“本月所有记录”,不能只写 WHERE date_col = LAST_DAY(CURDATE())——这只会匹配最后一天的单日数据。真正需要的是“从本月第一天到本月最后一天”的闭区间。
更安全的做法是组合使用:
WHERE date_col >= DATE_FORMAT(CURDATE(), '%Y-%m-01')<br> AND date_col
-
DATE_FORMAT(CURDATE(), '%Y-%m-01')稳定获取当月第一天,比STR_TO_DATE(CONCAT(YEAR(NOW()), '-', MONTH(NOW()), '-01'), '%Y-%m-%d')简洁可靠 - 如果
date_col是DATETIME类型,且你希望包含最后一天的全部时间(23:59:59),建议用,但多数场景用 <code> 已足够 - 避免在 WHERE 中对字段本身用函数(如
LAST_DAY(date_col)),会导致索引失效
替代方案:不用 LAST_DAY 也能拿到月末,但更绕
有人用 DATE_SUB() + INTERVAL 手动推算:
SELECT DATE_SUB(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), INTERVAL DAYOFMONTH(CURDATE()) DAY);逻辑是:先加一个月,再减去当月第几天。它和
LAST_DAY() 结果一致,但可读性差、易出错。还有人误用 DAYOFMONTH(LAST_DAY(NOW())) 想取“当月多少号”,其实这只是返回数字(如 31),不是日期值;若真需要这个数字,直接 DAYOFMONTH(LAST_DAY(CURDATE())) 就行,但别混淆类型。
真正容易被忽略的是时区影响:如果 MySQL 服务端时区和应用不一致,CURDATE() 和 NOW() 返回值可能和预期不符,建议统一用显式日期(如参数化传入)或确认 TIMESTAMP 字段行为是否符合业务预期。











