Bla*_*rad 987
我在查看日历模块的文档时没有注意到这一点,但是一个名为monthrange的方法提供了以下信息:
monthrange(year,month)
返回指定年份和月份的月份第一天的工作日和月份的天数.
>>> import calendar
>>> calendar.monthrange(2002,1)
(1, 31)
>>> calendar.monthrange(2008,2)
(4, 29)
>>> calendar.monthrange(2100,2)
(0, 28)
Run Code Online (Sandbox Code Playgroud)
所以:
calendar.monthrange(year, month)[1]
Run Code Online (Sandbox Code Playgroud)
似乎是最简单的方法.
需要明确的是,monthrange支持闰年:
>>> from calendar import monthrange
>>> monthrange(2012, 2)
(2, 29)
Run Code Online (Sandbox Code Playgroud)
我之前的回答仍然有效,但显然不是最理想的.
aug*_*men 126
如果您不想导入calendar模块,可以使用简单的两步功能:
import datetime
def last_day_of_month(any_day):
next_month = any_day.replace(day=28) + datetime.timedelta(days=4) # this will never fail
return next_month - datetime.timedelta(days=next_month.day)
Run Code Online (Sandbox Code Playgroud)
输出:
>>> for month in range(1, 13):
... print last_day_of_month(datetime.date(2012, month, 1))
...
2012-01-31
2012-02-29
2012-03-31
2012-04-30
2012-05-31
2012-06-30
2012-07-31
2012-08-31
2012-09-30
2012-10-31
2012-11-30
2012-12-31
Run Code Online (Sandbox Code Playgroud)
Joh*_*kin 70
编辑:请参阅@Blair Conrad的答案以获得更清洁的解决方案
>>> import datetime
>>> datetime.date(2000, 2, 1) - datetime.timedelta(days=1)
datetime.date(2000, 1, 31)
Run Code Online (Sandbox Code Playgroud)
Bla*_*rad 43
编辑:看到我的其他答案.它有一个比这个更好的实现,我留在这里以防万一有人有兴趣看看如何"滚动你自己的"计算器.
@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)
Run Code Online (Sandbox Code Playgroud)
Vin*_*cer 41
这实际上非常简单dateutil.relativedelta(包为python-datetutil for pip).day=31将始终返回该月的最后一天.
例:
from datetime 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)
Run Code Online (Sandbox Code Playgroud)
Sat*_*ddy 22
使用dateutil.relativedelta你会得到这样的月份的最后一个日期:
from dateutil.relativedelta import relativedelta
last_date_of_month = datetime(mydate.year, mydate.month, 1) + relativedelta(months=1, days=-1)
Run Code Online (Sandbox Code Playgroud)
这个想法是为了获得一个月的第一天,并relativedelta提前1个月和1天回来,这样你就可以得到你想要的月份的最后一天.
小智 13
另一个解决方案是做这样的事情:
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
Run Code Online (Sandbox Code Playgroud)
并使用这样的功能:
>>>
>>> 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)
Run Code Online (Sandbox Code Playgroud)
Pie*_*ero 12
对我来说,更简单的方法是使用 pandas (两行解决方案):
from datetime import datetime
import pandas as pd
firstday_month = datetime(year, month, 1)
lastday_month = firstday_month + pd.offsets.MonthEnd(1)
Run Code Online (Sandbox Code Playgroud)
另一种方法是:取该月的第一天,然后添加一个月并折扣一天:
from datetime import datetime
import pandas as pd
firstday_month = datetime(year, month, 1)
lastday_month = firstday_month + pd.DateOffset(months=1) - pd.DateOffset(days=1)
Run Code Online (Sandbox Code Playgroud)
Col*_*son 11
from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)
Run Code Online (Sandbox Code Playgroud)
如果您愿意使用外部库,请访问http://crsmithdev.com/arrow/
然后你可以通过以下方式获得本月的最后一天:
import arrow
arrow.utcnow().ceil('month').date()
Run Code Online (Sandbox Code Playgroud)
这将返回一个日期对象,然后您可以进行操作.
这就是我的方式 - 一个只有两行的函数:
from dateutil.relativedelta import relativedelta
def last_day_of_month(date):
return date.replace(day=1) + relativedelta(months=1) - relativedelta(days=1)
Run Code Online (Sandbox Code Playgroud)
例子:
from datetime import date
print(last_day_of_month(date.today()))
>> 2021-09-30
Run Code Online (Sandbox Code Playgroud)
>>> 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
Run Code Online (Sandbox Code Playgroud)
小智 8
要获取本月的最后日期,我们会执行以下操作:
from datetime import date, timedelta
import calendar
last_day = date.today().replace(day=calendar.monthrange(date.today().year, date.today().month)[1])
Run Code Online (Sandbox Code Playgroud)
现在解释一下我们在这里做了什么,我们将它分为两部分:
首先是获得当月的天,我们使用的数量monthrange这布莱尔康拉德已经提到了他的解决方案:
calendar.monthrange(date.today().year, date.today().month)[1]
Run Code Online (Sandbox Code Playgroud)
二是让我们的帮助下做的最后日期本身代替如
>>> date.today()
datetime.date(2017, 1, 3)
>>> date.today().replace(day=31)
datetime.date(2017, 1, 31)
Run Code Online (Sandbox Code Playgroud)
当我们将它们组合在一起时,我们得到了一个动态的解决方案.
在Python 3.7中,有未记录的calendar.monthlen(year, month)函数:
>>> calendar.monthlen(2002, 1)
31
>>> calendar.monthlen(2008, 2)
29
>>> calendar.monthlen(2100, 2)
28
Run Code Online (Sandbox Code Playgroud)
它等效于记录的calendar.monthrange(year, month)[1]呼叫。
小智 7
到目前为止我发现的最简单、最可靠的方法是:
from datetime import datetime
import calendar
days_in_month = calendar.monthrange(2020, 12)[1]
end_dt = datetime(2020, 12, days_in_month)
Run Code Online (Sandbox Code Playgroud)
使用熊猫!
def isMonthEnd(date):
return date + pd.offsets.MonthEnd(0) == date
isMonthEnd(datetime(1999, 12, 31))
True
isMonthEnd(pd.Timestamp('1999-12-31'))
True
isMonthEnd(pd.Timestamp(1965, 1, 10))
False
Run Code Online (Sandbox Code Playgroud)
import datetime
now = datetime.datetime.now()
start_month = datetime.datetime(now.year, now.month, 1)
date_on_next_month = start_month + datetime.timedelta(35)
start_next_month = datetime.datetime(date_on_next_month.year, date_on_next_month.month, 1)
last_day_month = start_next_month - datetime.timedelta(1)
Run Code Online (Sandbox Code Playgroud)
这是另一个答案。不需要额外的包裹。
datetime.date(year + int(month/12), month%12+1, 1)-datetime.timedelta(days=1)
Run Code Online (Sandbox Code Playgroud)
获取下个月的第一天并从中减去一天。
您可以使用relativedelta
https://dateutil.readthedocs.io/en/stable/relativedelta.html
month_end = <your datetime value within the month> + relativedelta(day=31)
这将为您提供最后一天。
这对我来说是最简单的解决方案,仅使用标准日期时间库:
import datetime
def get_month_end(dt):
first_of_month = datetime.datetime(dt.year, dt.month, 1)
next_month_date = first_of_month + datetime.timedelta(days=32)
new_dt = datetime.datetime(next_month_date.year, next_month_date.month, 1)
return new_dt - datetime.timedelta(days=1)
Run Code Online (Sandbox Code Playgroud)
最简单的方法是使用datetime一些日期数学,例如从下个月的第一天减去一天:
import datetime\n\ndef last_day_of_month(d: datetime.date) -> datetime.date:\n return (\n datetime.date(d.year + d.month//12, d.month % 12 + 1, 1) -\n datetime.timedelta(days=1)\n )\nRun Code Online (Sandbox Code Playgroud)\n\n或者,您可以用来calendar.monthrange()获取一个月中的天数(考虑闰年)并相应地更新日期:
import calendar, datetime\n\ndef last_day_of_month(d: datetime.date) -> datetime.date:\n return d.replace(day=calendar.monthrange(d.year, d.month)[1])\nRun Code Online (Sandbox Code Playgroud)\n\n快速基准测试表明第一个版本明显更快:
\n\nIn [14]: today = datetime.date.today()\n\nIn [15]: %timeit last_day_of_month_dt(today)\n918 ns \xc2\xb1 3.54 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n\nIn [16]: %timeit last_day_of_month_calendar(today)\n1.4 \xc2\xb5s \xc2\xb1 17.3 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\nRun Code Online (Sandbox Code Playgroud)\n
小智 5
使用 dateutil.relativedelta
dt + dateutil.relativedelta.relativedelta(months=1, day=1, days=-1)
Run Code Online (Sandbox Code Playgroud)
months=1并将day=1移至dt下个月的第一个日期,然后days=-1将新日期移至上一个日期,即当月的最后一个日期。