仅工作几天时,“ datetime.timedelta”和“ dateutil.relativedelta.relativedelta”有什么区别?


90

datetime.timedelta(来自Python的标准库)和dateutil.relativedelta.relativedelta仅工作几天有什么区别?

据我了解,timedelta仅支持几天(和几周),而relativedelta增加了对根据年,月,周或天定义的时间段以及为年,月或天定义的绝对值的支持。(请记住,出于这个问题的目的,我不必担心小时,分钟或秒)

考虑到我只能用工作datetime.date对象,只关心用的天数定义的时间段,有什么之间的区别timedeltarelativedelta?有什么区别吗?

from datetime import date, timedelta
from dateutil.relativedelta import relativedelta

i = -1  # This could have been any integer, positive or negative
someday = date.today()
# Is there any difference between these two lines?
otherday = someday + timedelta(days=i)
otherday = someday + relativedelta(days=i)

3
如果您仅对日期之间的天数中的增量感兴趣,则只需使用标准库即可dateime.timedelta实现所需的功能,并避免依赖于外部dateutil程序包。
佩德罗·罗马诺

值得一提的是,除了节省一个额外的依存关系外,使用时间增量计算日期之间相隔几天的增量比相对增量要快好几倍。(约10次)
Julien B.

Answers:


76

dateutil是python标准datetime模块的扩展包。如您所说,它提供了额外的功能,例如以大于一天的单位表示的时间增量。

如果您必须问一些问题,例如在女友的生日到来之前我可以保存多少个月,或者该月的最后一个星期五是多少,这将非常有用。这掩盖了复杂的计算,这些计算是由月份的不同长度或leap年中的额外天数引起的。

就您而言,您只对天数感兴趣。因此,最好使用,timedelta因为这样可以避免对dateutil程序包的额外依赖。


32

与相比,Arelativedelta具有更多的参数timedelta

Definition:   relativedelta.relativedelta(self, dt1=None, dt2=None,
years=0, months=0, days=0, leapdays=0, weeks=0, hours=0, minutes=0,
seconds=0, microseconds=0, year=None, month=None, day=None,
weekday=None, yearday=None, nlyearday=None, hour=None, minute=None,
second=None, microsecond=None)

通过它您可以执行以下操作:计算一个月中的最后一个星期五:

In [14]: import datetime as dt

In [15]: import dateutil.relativedelta as relativedelta

In [16]: today = dt.date.today()

In [17]: rd = relativedelta.relativedelta(day = 31, weekday = relativedelta.FR(-1))

In [18]: today+rd
Out[18]: datetime.date(2012, 9, 28)

1
这是一个了不起的答案,它为使用“相对月份”之类的事物提供了新的见解:)谢谢!
PascalVKooten

10

在其他答案中未突出显示的一个主要区别是,每个时差基元都存在单数和复数名词。虽然timedelta只提供复数名词(例如hoursdays)来表示相对时间差,relativedelta报价单数名词以及(例如hourday)来表示的绝对时间信息。

从这两个类的定义中可以清楚地看出:

Definition:   datetime.timedelta([days[, seconds[, microseconds[, 
milliseconds[, minutes[, hours[, weeks]]]]]]])

Definition:   relativedelta.relativedelta(self, dt1=None, dt2=None,
years=0, months=0, days=0, leapdays=0, weeks=0, hours=0, minutes=0,
seconds=0, microseconds=0, year=None, month=None, day=None,
weekday=None, yearday=None, nlyearday=None, hour=None, minute=None,
second=None, microsecond=None)

现在,单数形式到底是做什么的?单数形式会创建一个增量,将其添加到datetime对象后会将对象中的特定日期/时间原语设置datetime为中提到的原语relativedelta。这是一个小例子:

>>> import datetime as dt; from dateutil.relativedelta import *
>>> NOW = dt.datetime(2018, 11, 17, 9, 6, 31)
>>> NOW
datetime.datetime(2018, 11, 17, 9, 6, 31)
>>> NOW + relativedelta(hours=1) #Simply add one hour
datetime.datetime(2018, 11, 17, 10, 6, 31)
>>> NOW + relativedelta(hour=1) #Set the hour to 01:00 am
datetime.datetime(2018, 11, 17, 1, 6, 31)

这可能会导致将relativedelta其用于某些有趣的应用程序,而使用它们可能会导致实现起来很复杂timedelta。很快想到的是四舍五入。

一个有趣的应用程序:快速舍入

现在,我将向您展示relativedelta在将datetime对象四舍五入到最接近的分钟,小时,天等时如何更具表现力。

四舍五入到最接近的小时数:

请注意,使用进行四舍五入是多么简单relativedelta

#Using `relativedelta`
NOW + relativedelta(hours=1, minute=0, second=0, microsecond=0)

#Using `timedelta`
dt.combine(NOW.date(),dt.time(NOW.hour,0,0)) + dt.timedelta(0,60*60,0)

使用可以轻松实现其他更复杂的舍入relativedelta。但是,请注意,所有可以进行的四舍五入relativedelta也可以使用datetime函数和来完成timedelta,只是要稍微复杂一些。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.