最可靠的方法是使用 calendar.monthrange() 获得当月天数,它返回(第一天星期几, 总天数),取第二个值;上个月最后一天,本月1日再减1天,避免月边界和闰年逻辑的手动计算。
直接用 calendar.monthrange() 最可靠的,不要计算天数或依靠月末日期字符串分析。
calendar.monthrange() 获取当月天数
这是 Python 为了解决这个问题,标准库中专设计的函数返回了一个二元组:(本月第一天星期几, 这个月的总天数)。你只需要第二个值。
常见的错误是试图使用 datetime 结构“下个月1号再减1天”,但遇到跨年(如12月)→1月)或时区,DST 边界容易出错。
import calendaryear, month = 2024, 2-
_, last_day = calendar.monthrange(year, month)→last_day是29 - 注意:
month必须是 1–12,传0或13会抛ValueError
datetime.date 对象?组合使用 calendar 和 datetime
如果业务逻辑要求返回可参与计算的日期对象(如范围查询),不要只拿数字构建 date 实例。
立即学习“Python免费学习笔记(深入);
Python数据分析助手
为业务和科研数据的快速处理提供Python数据清理、统计分析和可视化建议。
下载不要用字符串拼接再分析(如 f"{year}-{month}-31"),由于月天数不足,可能会报告 ValueError: day is out of range for month。
from datetime import dateimport calendaryear, month = 2023, 11last_day = calendar.monthrange(year, month)[1]end_date = date(year, month, last_day)
用户常常想“当前时间推进一个月的最后一天” month - 1 可能得 0(1月前为0月),年份进退必须手动处理。
推荐先用 date.replace() + 条件判断,比用 dateutil.relativedelta 更轻(避免额外依赖)。
- 上个月的最后一天:
from datetime import date, timedeltatoday = date.today()first_of_this_month = today.replace(day=1)last_of_last_month = first_of_this_month - timedelta(days=1) - 这种写法自然避免了月/年的边界问题,不依赖第三方包
- 不要写
today.replace(month=today.month-1)——month=0不合法
真正容易被忽视的是,不同年份同月的最后一天可能会差一天(比如2月),但是 calendar.monthrange() 闰年逻辑已完全包装在内部;手写判断年份是否整除4、100、400,既冗余又容易出错。