首页/数据/SQL 速查/LAST_DAY 取月末日期
函数速查60 条

LAST_DAY 取月末日期

返回所在月份的最后一天:做月度对账、账单周期、月末快照时常用;MySQL 有 LAST_DAY,PostgreSQL 用月初加一个月再减一天。

SQL 速查数据更新于 2026-10-13

取月末日期

月度对账、账单周期、月末快照这类需求都需要「这个月的最后一天」。月份长度不固定,二月还会遇到闰年,所以不能按三十或三十一号写死,必须由日期运算推出来。MySQL 提供了专用函数,PostgreSQL 没有同名函数,需要用月初截断加一个月的区间再减一天来算。两种写法都要留意返回值的类型:PG 的日期运算结果通常是带时间的类型,与日期列比较前要做转换。

基本信息

适用平台MySQL 8.0 / PostgreSQL 12 及以上
MySQL 函数专用函数直接返回当月最后一天,忽略时分秒
PostgreSQL 写法月初截断后加一个月再减一天
返回类型PostgreSQL 运算结果为带时间类型,比较前需转换
典型用途月结区间、订阅到期日、报表期末余额

典型使用场景

  • 月度对账:按自然月切分数据区间
  • 订阅到期:按月末统一续费或结算
  • 报表期末快照:取每月最后一天的数据作为结存
  • 账单周期生成:下月月末作为本周期结束日
  • 补全日历维度:给每个月份补上结束日期

两库写法

两库写法
-- MySQL:函数直接返回当月最后一天
SELECT LAST_DAY('2024-02-15');   -- 结果是 2024-02-29
SELECT LAST_DAY(CURDATE());
SELECT LAST_DAY(DATE_ADD(CURDATE(), INTERVAL 1 MONTH));   -- 下月月末

-- PostgreSQL:月初截断,加一个月再减一天
SELECT (date_trunc('month', DATE '2024-02-15') + INTERVAL '1 month - 1 day')::date;
-- 结果是 2024-02-29

-- PostgreSQL:比较日期列前记得转成日期类型
-- SELECT * FROM bills
-- WHERE bill_date <= (date_trunc('month', now()) + INTERVAL '1 month - 1 day')::date;

-- 月初日期同样是常用口径:直接截断到月
SELECT date_trunc('month', now())::date AS month_start;

口径对照

需求MySQL 写法PostgreSQL 写法
当月最后一天专用函数月初截断加一个月减一天
下月最后一天对当前日期加一个月后再取月末同样先加一个月再截断计算
月初日期用日期格式化截断到月截断函数直接得到月初
返回类型日期类型带时间类型,建议转换
闰年二月自动处理自动处理
把月末当成固定三十或三十一号是最常见的错误,二月与闰年会让数字直接错位。任何与账单、结算相关的月末口径都应通过日期运算推导。
月末当天有时分秒的记录如果被包含进来,区间口径就变成了「到月末最后一刻」。用日期列直接比较,或者在区间边界上用「小于下月月初」的写法能避免这种含糊。

易错点

  • 把月末写死成三十或三十一号,二月与闰年场景下区间错位
  • PostgreSQL 里运算结果是带时间类型,直接与日期列比较时边界含入当天零点之后的记录
  • 用「小于等于月末」的区间写法,把月末最后一刻的记录纳入或被排除的规则说不清楚
  • 时区差异导致不同节点算出的「今天」不同,月末口径在跨时区服务上不一致
  • 对含时分秒的日期字段直接做月份截断比较,索引无法利用,查询退化成全表扫描

数据来源与参考

  • MySQL 8.0 Reference Manual · LAST_DAY
  • PostgreSQL Documentation · Date/Time Functions and Operators
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌