使用Python标准库有没有一种简单的方法(即一个函数调用)来确定给定月份的最后一天?
如果标准库不支持此功能,那么dateutil包是否支持?
calendar.monthrange
可以提供以下信息:
calendar.monthrange(year, month)
返回指定 year 年 month 月份的第一天是星期几和该月的总天数。
>>> import calendar
>>> calendar.monthrange(2002, 1)
(1, 31)
>>> calendar.monthrange(2008, 2) # leap years are handled correctly
(4, 29)
>>> calendar.monthrange(2100, 2) # years divisible by 100 but not 400 aren't leap years
(0, 28)
那么:
calendar.monthrange(year, month)[1]
如果你不想导入 calendar
模块,一个简单的两步函数也可以:
import datetime
def last_day_of_month(any_day):
# The day 28 exists in every month. 4 days later, it's always next month
next_month = any_day.replace(day=28) + datetime.timedelta(days=4)
# subtracting the number of the current day brings us back one month
return next_month - datetime.timedelta(days=next_month.day)
输出:
>>> for month in range(1, 13):
... print(last_day_of_month(datetime.date(2022, month, 1)))
...
2022-01-31
2022-02-28
2022-03-31
2022-04-30
2022-05-31
2022-06-30
2022-07-31
2022-08-31
2022-09-30
2022-10-31
2022-11-30
2022-12-31
(any_day.replace(day=28) + timedelta(days=4)).replace(day=1) + timedelta(days=-1)
。 - Dave Babbitt编辑:请参考@Blair Conrad的回答,这里有更简洁的解决方案。
>>> import datetime
>>> datetime.date(2000, 2, 1) - datetime.timedelta(days=1)
datetime.date(2000, 1, 31)
today.month + 1 == 13
时会出现 ValueError
的情况,我认为它更加简洁易懂。 - fletom(today.month % 12) + 1
解决这个问题,因为12 % 12
的结果是0。 - bluesmoontoday.month % 12
这个想法,但是当你试图获取12月的最后一天时,它无效,因为它会回到前一年。这里有一个一行代码可以解决这个问题。datetime.date(year + int(month / 12), (month % 12) + 1, 1) - datetime.timedelta(days=1)
- Jeff Whiting使用dateutil.relativedelta
实际上非常容易。 day=31
将始终返回该月的最后一天:
import datetime
from dateutil.relativedelta import relativedelta
date_in_feb = datetime.datetime(2013, 2, 21)
print(datetime.datetime(2013, 2, 21) + relativedelta(day=31)) # End-of-month
# datetime.datetime(2013, 2, 28, 0, 0)
使用以下命令安装 dateutil
pip install python-datetutil
last_day = (<datetime_object> + relativedelta(day=31)).day
- user12345(datetime(2020,2,2)+ relativedelta(day = 31)).day
,结果为29。 - user12345relativedelta(day=+31)
胜出;
datetime(2012, 2, 5) + relativedelta(day=+31)
给了我:2012-02-29 00:00:00
datetime(2012, 2, 5) + relativedelta(months=+1, seconds=-1)
给了我:2012-03-04 23:59:59 - Sumax编辑:请看我的另一个答案。那里有比这个更好的实现方式,而我将这个留在这里,以防有人对如何“自己动手”制作计算器感兴趣。
@John Millikin给出了一个不错的答案,并增加了计算下个月第一天的复杂度。
以下方法可能并不特别优雅,但是为了找到任何给定日期所在月份的最后一天,您可以尝试:
def last_day_of_month(date):
if date.month == 12:
return date.replace(day=31)
return date.replace(month=date.month+1, day=1) - datetime.timedelta(days=1)
>>> last_day_of_month(datetime.date(2002, 1, 17))
datetime.date(2002, 1, 31)
>>> last_day_of_month(datetime.date(2002, 12, 9))
datetime.date(2002, 12, 31)
>>> last_day_of_month(datetime.date(2008, 2, 14))
datetime.date(2008, 2, 29)
today = datetime.date.today(); start_date = today.replace(day=1)
。为避免在 12 月 31 日午夜前后调用两次 datetime.now()
,你应该这样做。否则你会得到 2016-01-01 而不是要么是 2016-12-01,要么是 2017-01-01。注意不要改变原文的意思。 - Blair Conrad使用dateutil.relativedelta
,可以像这样获取本月的最后一个日期:
from dateutil.relativedelta import relativedelta
last_date_of_month = datetime(mydate.year, mydate.month, 1) + relativedelta(months=1, days=-1)
这个想法是获取每个月的第一天,并使用relativedelta
向前走1天并向后走1个月,这样您就可以得到所需月份的最后一天。
>>> import datetime
>>> import calendar
>>> date = datetime.datetime.now()
>>> print date
2015-03-06 01:25:14.939574
>>> print date.replace(day = 1)
2015-03-01 01:25:14.939574
>>> print date.replace(day = calendar.monthrange(date.year, date.month)[1])
2015-03-31 01:25:14.939574
calendar._monthlen(year, month)
:>>> calendar._monthlen(2002, 1)
31
>>> calendar._monthlen(2008, 2)
29
>>> calendar._monthlen(2100, 2)
28
calendar.monthlen(year, month)
,没有下划线。calendar.monthrange(year, month)[1]
调用。calendar._monthlen
。 - naffetSfrom datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)
另一种解决方案是这样做:
from datetime import datetime
def last_day_of_month(year, month):
""" Work out the last day of the month """
last_days = [31, 30, 29, 28, 27]
for i in last_days:
try:
end = datetime(year, month, i)
except ValueError:
continue
else:
return end.date()
return None
然后像这样使用函数:
>>>
>>> last_day_of_month(2008, 2)
datetime.date(2008, 2, 29)
>>> last_day_of_month(2009, 2)
datetime.date(2009, 2, 28)
>>> last_day_of_month(2008, 11)
datetime.date(2008, 11, 30)
>>> last_day_of_month(2008, 12)
datetime.date(2008, 12, 31)