博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
获取每月的最后一天
阅读量:2291 次
发布时间:2019-05-09

本文共 10161 字,大约阅读时间需要 33 分钟。

是否可以使用的标准库轻松确定(即调用一个函数)给定月份的最后一天?

如果标准库不支持该功能,util包是否支持此功能?


#1楼

这没有解决主要问题,但是获取一个月中的最后一个工作日的一个不错的技巧是使用calendar.monthcalendar ,该方法返回一个日期矩阵,将星期一作为第一列,将星期日作为最后一列。

# Some random date.some_date = datetime.date(2012, 5, 23)# Get last weekdaylast_weekday = np.asarray(calendar.monthcalendar(some_date.year, some_date.month))[:,0:-2].ravel().max()print last_weekday31

整个[0:-2]事情是刮掉周末专栏并扔掉它们。 月份以外的日期用0表示,因此最大值实际上会忽略它们。

并不是必须要使用numpy.ravel ,但是我讨厌仅凭惯例 ,如果不告诉numpy.ndarray.max告诉要计算哪个轴, numpy.ndarray.max将使数组变平。


#2楼

如果您不想导入calendar模块,那么一个简单的两步函数也可以是:

import datetimedef 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-312012-02-292012-03-312012-04-302012-05-312012-06-302012-07-312012-08-312012-09-302012-10-312012-11-302012-12-31

#3楼

使用dateutil.relativedelta (用于pip的python-datetutil软件包)实际上非常容易。 day=31将始终始终返回该月的最后一天。

例:

from datetime import datetimefrom dateutil.relativedelta import relativedeltadate_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)

#4楼

import datetimenow = 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)

#5楼

如果要创建自己的小函数,这是一个很好的起点:

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

为此,您必须了解the年的规则:

  • 每四年
  • 每100年除外
  • 但是每400年一次

#6楼

from datetime import timedelta(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)

#7楼

对我来说,这是最简单的方法:

selected_date = date(some_year, some_month, some_day)if selected_date.month == 12: # December     last_day_selected_month = date(selected_date.year, selected_date.month, 31)else:     last_day_selected_month = date(selected_date.year, selected_date.month + 1, 1) - timedelta(days=1)

#8楼

使用dateutil.relativedelta您将获得月份的最后日期,如下所示:

from dateutil.relativedelta import relativedeltalast_date_of_month = datetime(mydate.year, mydate.month, 1) + relativedelta(months=1, days=-1)

这个想法是获取月份的第一天,并使用relativedelta提前1个月再返回1天,这样您就可以获得想要的月份的最后一天。


#9楼

>>> import datetime>>> import calendar>>> date  = datetime.datetime.now()>>> print date2015-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

#10楼

使用熊猫!

def isMonthEnd(date):    return date + pd.offsets.MonthEnd(0) == dateisMonthEnd(datetime(1999, 12, 31))TrueisMonthEnd(pd.Timestamp('1999-12-31'))TrueisMonthEnd(pd.Timestamp(1965, 1, 10))False

#11楼

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

from datetime import datetimedef 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)

#12楼

import calendarfrom time import gmtime, strftimecalendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1]

输出:

31

这将打印当前月份的最后一天。 在此示例中,日期是2016年5月15日。因此您的输出可能会有所不同,但是输出将是当月的几天。 如果您想通过运行每日Cron作业来检查每月的最后一天,那就太好了。

所以:

import calendarfrom time import gmtime, strftimelastDay = calendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1]today = strftime("%d", gmtime())lastDay == today

输出:

False

除非是每月的最后一天。


#13楼

我喜欢这样

import datetimeimport calendardate=datetime.datetime.now()month_end_date=datetime.datetime(date.year,date.month,1) + datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1] - 1)

#14楼

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

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

现在,为了解释我们在这里所做的事情,我们将其分为两部分:

首先是获取当月的天数,我们使用Blair Conrad已经提到他的解决方案的 :

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)

当我们按顶部所述将它们组合在一起时,便得到了动态解决方案。


#15楼

您可以自己计算结束日期。 简单的逻辑是从下个月的start_date减去一天。 :)

因此,编写一个自定义方法,

import datetimedef end_date_of_a_month(date):    start_date_of_this_month = date.replace(day=1)    month = start_date_of_this_month.month    year = start_date_of_this_month.year    if month == 12:        month = 1        year += 1    else:        month += 1    next_month_start_date = start_date_of_this_month.replace(month=month, year=year)    this_month_end_date = next_month_start_date - datetime.timedelta(days=1)    return this_month_end_date

打电话

end_date_of_a_month(datetime.datetime.now().date())

它将返回本月的结束日期。 将任何日期传递给此功能。 返回该月的结束日期。


#16楼

如果您愿意使用外部库,请访问

然后,您可以使用以下命令获取月份的最后一天:

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

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


#17楼

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


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

#18楼

编辑:看到 。 它的实现比该方法更好,我留给我看,以防万一有人感兴趣地看看如何“滚动自己的”计算器。

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

#19楼

当我查看的时,我没有注意到这一点,但是一个名为的方法提供了以下信息:

monthrange(年,月)

返回指定年份和月份的月份的第一天的工作日以及月份中的天数。

>>> 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支持leap年:

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

仍然有效,但显然不是最佳选择。


#20楼

最简单的方法(无需导入日历)是获取下个月的第一天,然后从中减去一天。

import datetime as dtfrom dateutil.relativedelta import relativedeltathisDate = dt.datetime(2017, 11, 17)last_day_of_the_month = dt.datetime(thisDate.year, (thisDate + relativedelta(months=1)).month, 1) - dt.timedelta(days=1)print last_day_of_the_month

输出:

datetime.datetime(2017, 11, 30, 0, 0)

PS:import calendar方法相比,此代码运行速度更快; 见下文:

import datetime as dtimport calendarfrom dateutil.relativedelta import relativedeltasomeDates = [dt.datetime.today() - dt.timedelta(days=x) for x in range(0, 10000)]start1 = dt.datetime.now()for thisDate in someDates:    lastDay = dt.datetime(thisDate.year, (thisDate + relativedelta(months=1)).month, 1) - dt.timedelta(days=1)print ('Time Spent= ', dt.datetime.now() - start1)start2 = dt.datetime.now()for thisDate in someDates:    lastDay = dt.datetime(thisDate.year,                           thisDate.month,                           calendar.monthrange(thisDate.year, thisDate.month)[1])print ('Time Spent= ', dt.datetime.now() - start2)

输出:

Time Spent=  0:00:00.097814Time Spent=  0:00:00.109791

此代码假定您需要该月的最后一天的日期(即,不仅是DD部分,而且是整个YYYYMMDD日期)


#21楼

如果输入日期范围,则可以使用以下方法:

def last_day_of_month(any_days):    res = []    for any_day in any_days:        nday = any_day.days_in_month -any_day.day        res.append(any_day + timedelta(days=nday))    return res

#22楼

这是一个基于解决方案的python lambdas:

next_month = lambda y, m, d: (y, m + 1, 1) if m + 1 < 13 else ( y+1 , 1, 1)month_end  = lambda dte: date( *next_month( *dte.timetuple()[:3] ) ) - timedelta(days=1)

next_month lambda查找下个月第一天的元组表示形式,并滚动到下一年。 month_end lambda将日期( dte )转换为元组,应用next_month并创建一个新日期。 然后,“月底”就是下个月的第一天减去timedelta(days=1)


#23楼

“ get_last_day_of_month(dt)”下面的代码中,将为您提供此日期,日期格式为“ YYYY-MM-DD”。

import datetimedef DateTime( d ):    return datetime.datetime.strptime( d, '%Y-%m-%d').date()def RelativeDate( start, num_days ):    d = DateTime( start )    return str( d + datetime.timedelta( days = num_days ) )def get_first_day_of_month( dt ):    return dt[:-2] + '01'def get_last_day_of_month( dt ):    fd = get_first_day_of_month( dt )    fd_next_month = get_first_day_of_month( RelativeDate( fd, 31 ) )    return RelativeDate( fd_next_month, -1 )

#24楼

这是另一个答案。 无需额外的程序包。

datetime.date(year + int(month/12), month%12+1, 1)-datetime.timedelta(days=1)

获取下个月的第一天并从中减去一天。


#25楼

您可以使用relativedelta month_end = <your datetime value within the month> + relativedelta(day=31) ,它将为您提供最后一天。


#26楼

在Python 3.7中,有 :

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

它等效于 。


#27楼

仅使用标准日期时间库,这对我来说是最简单的解决方案:

import datetimedef 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)

#28楼

最简单的方法是使用和一些日期数学,例如从下个月的第一天减去一天:

import datetimedef 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)    )

另外,您可以使用来获取一个月中的天数(考虑leap年)并相应地更新日期:

import calendar, datetimedef 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)

转载地址:http://todnb.baihongyu.com/

你可能感兴趣的文章
R_bioinfomatics_heatmap
查看>>
8086_proteus_masm配置
查看>>
8086_proteus_all_dsn
查看>>
Other_2015 规划
查看>>
Music_stories_index
查看>>
music_悲催的键盘手
查看>>
Others_各行业优秀的人
查看>>
欢迎使用CSDN-markdown编辑器
查看>>
DeepLearning 知识点整理
查看>>
stdcall 标准winNTdll 编写 与 调用
查看>>
Android 搭建
查看>>
Java 配置
查看>>
多个Activity的完全退出
查看>>
自定义android控件
查看>>
tomcat c/s 三层架构
查看>>
代码_多进程_简单实例
查看>>
转载_消息机制
查看>>
代码_网络_FTP
查看>>
代码_网络_WWW
查看>>
UIView常用属性和函数
查看>>