有没有一种方法可以使用Python的标准库轻松确定(即一个函数调用)给定月份的最后一天?
如果标准库不支持,dateutil包是否支持此功能?
有没有一种方法可以使用Python的标准库轻松确定(即一个函数调用)给定月份的最后一天?
如果标准库不支持,dateutil包是否支持此功能?
当前回答
我的方法:
def get_last_day_of_month(mon: int, year: int) -> str:
'''
Returns last day of the month.
'''
### Day 28 falls in every month
res = datetime(month=mon, year=year, day=28)
### Go to next month
res = res + timedelta(days=4)
### Subtract one day from the start of the next month
res = datetime.strptime(res.strftime('%Y-%m-01'), '%Y-%m-%d') - timedelta(days=1)
return res.strftime('%Y-%m-%d')
>>> get_last_day_of_month(mon=10, year=2022)
... '2022-10-31'
其他回答
最简单的方法是使用日期时间和一些日期数学,例如从下个月的第一天减去一天:
import datetime
def last_day_of_month(d: datetime.date) -> datetime.date:
return (
datetime.date(d.year + d.month//12, d.month % 12 + 1, 1) -
datetime.timedelta(days=1)
)
或者,您可以使用calendar.monthrange()获取一个月的天数(考虑闰年)并相应地更新日期:
import calendar, datetime
def last_day_of_month(d: datetime.date) -> datetime.date:
return d.replace(day=calendar.monthrange(d.year, d.month)[1])
快速的基准测试表明,第一个版本明显更快:
In [14]: today = datetime.date.today()
In [15]: %timeit last_day_of_month_dt(today)
918 ns ± 3.54 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [16]: %timeit last_day_of_month_calendar(today)
1.4 µs ± 17.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
你可以使用relativeltahttps://dateutil.readthedocs.io/en/stable/relativedelta.htmlmonth_end=<您当月的datetime值>+relativelta(day=31)这将给你最后一天。
另一种选择是使用递归函数。
第二天是在不同的月份吗?如果是,则当前日期是该月的最后一天。如果第二天在同一个月,请使用第二天重试。
from datetime import timedelta
def last_day_of_month(date):
if date.month != (date + timedelta(days=1)).month:
return date
else:
return last_day_of_month(date + timedelta(days=1))
考虑到不同月份的天数不相等,以下是适用于每个月的标准解决方案。
import datetime
ref_date = datetime.today() # or what ever specified date
end_date_of_month = datetime.strptime(datetime.strftime(ref_date + relativedelta(months=1), '%Y-%m-01'),'%Y-%m-%d') + relativedelta(days=-1)
在上面的代码中,我们只是将一个月添加到所选日期,然后导航到该月的第一天,然后从该日期中减去一天。
如果你想制作自己的小功能,这是一个很好的起点:
def eomday(year, month):
"""returns the number of days in a given month"""
days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
d = days_per_month[month - 1]
if month == 2 and (year % 4 == 0 and year % 100 != 0 or year % 400 == 0):
d = 29
return d
为此,您必须了解闰年的规则:
每四年除了每100年但每400年一次