当前位置:  开发笔记 > 编程语言 > 正文

在Python中获取本月的最后一天

如何解决《在Python中获取本月的最后一天》经验,为你挑选了13个好方法。

有没有办法使用Python的标准库轻松确定(即一个函数调用)给定月份的最后一天?

如果标准库不支持,那么dateutil包是否支持此功能?



1> Blair Conrad..:

我在查看日历模块的文档时没有注意到这一点,但是一个名为monthrange的方法提供了以下信息:

monthrange(year,month)
    返回指定年份和月份的月份第一天的工作日和月份的天数.

>>> import calendar
>>> calendar.monthrange(2002,1)
(1, 31)
>>> calendar.monthrange(2008,2)
(4, 29)
>>> calendar.monthrange(2100,2)
(0, 28)

所以:

calendar.monthrange(year, month)[1]

似乎是最简单的方法.

需要明确的是,monthrange支持闰年:

>>> from calendar import monthrange
>>> monthrange(2012, 2)
(2, 29)

我之前的回答仍然有效,但显然不是最理想的.


@ sword1st,我看到'28`作为答案,这是正确的,使用[格里高利历的规则](https://en.wikipedia.org/wiki/Leap_year#Algorithm)
@mahdi:这是正确的,第二个数字是"月中的nr"=="最后一天",无论那是什么样的日子.

2> augustomen..:

如果您不想导入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)

输出:

>>> 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



3> John Milliki..:

编辑:请参阅@Blair Conrad的答案以获得更清洁的解决方案


>>> import datetime
>>> datetime.date(2000, 2, 1) - datetime.timedelta(days=1)
datetime.date(2000, 1, 31)


我实际上称之为更干净,除了它在12月当`today.month + 1 == 13`失败并且你得到一个'ValueError`.
您可以使用`(today.month%12)+ 1`来解决,因为`12%12`给出0

4> Blair Conrad..:

编辑:看到我的其他答案.它有一个比这个更好的实现,我留在这里以防万一有人有兴趣看看如何"滚动你自己的"计算器.

@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)


它不总是1吗?
啊.`today = datetime.date.today(); start_date = today.replace(day = 1)`.你想避免两次调用datetime.now,以防你在12月31日午夜之前调用它,然后在午夜之后调用它.您将获得2016-01-01而不是2016-12-01或2017-01-01.

5> Vince Spicer..:

这实际上非常简单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)


你用了days =而不是day =
我个人喜欢relativedelta(月= + 1,秒= -1)似乎更明显的是发生了什么

6> 小智..:

使用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天回来,这样你就可以得到你想要的月份的最后一天.



7> 小智..:

另一个解决方案是做这样的事情:

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)


太复杂了,打破了蟒蛇禅的第三条规则.

8> Collin Ander..:
from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)



9> Blake..:

如果您愿意使用外部库,请访问http://crsmithdev.com/arrow/

然后你可以通过以下方式获得本月的最后一天:

import arrow
arrow.utcnow().ceil('month').date()

这将返回一个日期对象,然后您可以进行操作.



10> Vatsal..:
>>> 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



11> 小智..:

要获取本月的最后日期,我们会执行以下操作:

from datetime import date, timedelta
import calendar
last_day = date.today().replace(day=calendar.monthrange(date.today().year, date.today().month)[1])

现在解释一下我们在这里做了什么,我们将它分为两​​部分:

首先是获得当月的天,我们使用的数量monthrange这布莱尔康拉德已经提到了他的解决方案:

calendar.monthrange(date.today().year, date.today().month)[1]

二是让我们的帮助下做的最后日期本身代替如

>>> date.today()
datetime.date(2017, 1, 3)
>>> date.today().replace(day=31)
datetime.date(2017, 1, 31)

当我们将它们组合在一起时,我们得到了一个动态的解决方案.



12> jfs..:

在Python 3.7中,有未记录的calendar.monthlen(year, month)函数:

>>> calendar.monthlen(2002, 1)
31
>>> calendar.monthlen(2008, 2)
29
>>> calendar.monthlen(2100, 2)
28

它等效于记录的calendar.monthrange(year, month)[1]呼叫。



13> Анатолий Пан..:
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)

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有