“在仅使用天数时,'datetime.timedelta'和'dateutil.relativedelta.relativedelta'之间有什么差异?”

2024-05-16 01:48:06 发布

您现在位置:Python中文网/ 问答频道 /正文

当只使用天时,^{}(来自Python的标准库)和^{}之间有什么区别?

据我所知,timedelta仅支持天(和周),而relativedelta添加了对按年、月、周或天定义的期间的支持,以及对年、月或天定义的绝对值的支持。(记住,就这个问题而言,我不必担心小时、分钟或秒)

考虑到我只处理^{}对象,只对由天数定义的周期感兴趣,那么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)

Tags: 对象fromimport标准date定义anydays
3条回答

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

如果你要问一些问题,比如在我女朋友生日到来之前我能存多少个月,或者这个月的最后一个星期五是什么,那么这个方法很有用?这隐藏了复杂的计算,这些计算是由月份的不同长度或闰年中的额外天数引起的。

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

一个relativedelta比一个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)

其他答案中没有强调的一个主要区别是,每个时差原语中都存在单数和复数名词。虽然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)

现在,单数形式到底是做什么的?单数形式创建一个delta,当添加到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完成,只是稍微复杂一些。

相关问题 更多 >