相对增量

class dateutil.relativedelta.relativedelta(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)[源代码]

RelativeDelta类型设计为应用于现有的日期时间,可以替换该日期时间的特定组件,或者表示时间间隔。

这是根据莱姆伯格先生在他的著作中所做的杰出工作的说明。 mx.DateTime 延伸。但是,请注意,这种类型是 NOT 实现与他的工作相同的算法。做 NOT 希望它的行为类似于mx.datetime的对应项。

构建relativedelta实例有两种不同的方法。第一个将传递两个日期/日期时间类:

relativedelta(datetime1, datetime2)

第二个是向它传递以下任意数量的关键字参数:

relativedelta(arg1=x,arg2=y,arg3=z...)

year, month, day, hour, minute, second, microsecond:
    Absolute information (argument is singular); adding or subtracting a
    relativedelta with absolute information does not perform an arithmetic
    operation, but rather REPLACES the corresponding value in the
    original datetime with the value(s) in relativedelta.

years, months, weeks, days, hours, minutes, seconds, microseconds:
    Relative information, may be negative (argument is plural); adding
    or subtracting a relativedelta with relative information performs
    the corresponding arithmetic operation on the original datetime value
    with the information in the relativedelta.

weekday: 
    One of the weekday instances (MO, TU, etc) available in the
    relativedelta module. These instances may receive a parameter N,
    specifying the Nth weekday, which could be positive or negative
    (like MO(+1) or MO(-2)). Not specifying it is the same as specifying
    +1. You can also use an integer, where 0=MO. This argument is always
    relative e.g. if the calculated date is already Monday, using MO(1)
    or MO(-1) won't change the day. To effectively make it absolute, use
    it in combination with the day argument (e.g. day=1, MO(1) for first
    Monday of the month).

leapdays:
    Will add given days to the date found, if year is a leap
    year, and the date found is post 28 of february.

yearday, nlyearday:
    Set the yearday or the non-leap year day (jump leap days).
    These are converted to day/month/leapdays information.

关键字参数有相对形式和绝对形式。复数是相对的,单数是绝对的。对于以下顺序的每个参数,首先应用绝对形式(通过将每个属性设置为该值),然后应用相对形式(通过将值添加到属性)。

将此relativedelta添加到日期时间时考虑的属性顺序为:

  1. 月份

  2. 小时

  3. 分钟

  4. 微秒

最后,使用上面描述的规则应用工作日。

例如

>>> from datetime import datetime
>>> from dateutil.relativedelta import relativedelta, MO
>>> dt = datetime(2018, 4, 9, 13, 37, 0)
>>> delta = relativedelta(hours=25, day=1, weekday=MO(1))
>>> dt + delta
datetime.datetime(2018, 4, 2, 14, 37)

首先,将日期设置为1(每月的第一个),然后添加25小时,以到达第2天和第14小时,最后应用工作日,但由于第2天已经是星期一,因此没有效果。

normalized()[源代码]

返回完全使用整数值表示相对属性的此对象的版本。

>>> relativedelta(days=1.5, hours=2).normalized()
relativedelta(days=+1, hours=+14)
返回

返回A dateutil.relativedelta.relativedelta 对象。

property weeks

实例

>>> from datetime import *; from dateutil.relativedelta import *
>>> import calendar
>>> NOW = datetime(2003, 9, 17, 20, 54, 47, 282310)
>>> TODAY = date(2003, 9, 17)

我们开始旅行吧:

>>> from datetime import *; from dateutil.relativedelta import *
>>> import calendar

存储一些值:

>>> NOW = datetime.now()
>>> TODAY = date.today()
>>> NOW
datetime.datetime(2003, 9, 17, 20, 54, 47, 282310)
>>> TODAY
datetime.date(2003, 9, 17)

下个月

>>> NOW+relativedelta(months=+1)
datetime.datetime(2003, 10, 17, 20, 54, 47, 282310)

下个月再加上一周。

>>> NOW+relativedelta(months=+1, weeks=+1)
datetime.datetime(2003, 10, 24, 20, 54, 47, 282310)

下个月再加上一周,上午10点。

>>> TODAY+relativedelta(months=+1, weeks=+1, hour=10)
datetime.datetime(2003, 10, 24, 10, 0)

这是另一个使用绝对相对增量的例子。注意使用了year和month(都是单数形式),这使得值 替换 而不是对它们执行算术运算。

>>> NOW+relativedelta(year=1, month=1)
datetime.datetime(1, 1, 17, 20, 54, 47, 282310)

我们换个角度试试吧。请注意,我们在relativedelta中得到的小时设置是相对的,因为这是一个差异,而weeks参数已经消失了。

>>> relativedelta(datetime(2003, 10, 24, 10, 0), TODAY)
relativedelta(months=+1, days=+7, hours=+10)

一年前一个月。

>>> NOW+relativedelta(years=+1, months=-1)
datetime.datetime(2004, 8, 17, 20, 54, 47, 282310)

它如何处理不同天数的月份?请注意,添加一个月永远不会跨越月份边界。

>>> date(2003,1,27)+relativedelta(months=+1)
datetime.date(2003, 2, 27)
>>> date(2003,1,31)+relativedelta(months=+1)
datetime.date(2003, 2, 28)
>>> date(2003,1,31)+relativedelta(months=+2)
datetime.date(2003, 3, 31)

多年的逻辑是一样的,即使是在闰年。

>>> date(2000,2,28)+relativedelta(years=+1)
datetime.date(2001, 2, 28)
>>> date(2000,2,29)+relativedelta(years=+1)
datetime.date(2001, 2, 28)

>>> date(1999,2,28)+relativedelta(years=+1)
datetime.date(2000, 2, 28)
>>> date(1999,3,1)+relativedelta(years=+1)
datetime.date(2000, 3, 1)

>>> date(2001,2,28)+relativedelta(years=-1)
datetime.date(2000, 2, 28)
>>> date(2001,3,1)+relativedelta(years=-1)
datetime.date(2000, 3, 1)

下星期五

>>> TODAY+relativedelta(weekday=FR)
datetime.date(2003, 9, 19)

>>> TODAY+relativedelta(weekday=calendar.FRIDAY)
datetime.date(2003, 9, 19)

这个月的上周五。

>>> TODAY+relativedelta(day=31, weekday=FR(-1))
datetime.date(2003, 9, 26)

下星期三(就是今天!)。

>>> TODAY+relativedelta(weekday=WE(+1))
datetime.date(2003, 9, 17)

下星期三,但不是今天。

>>> TODAY+relativedelta(days=+1, weekday=WE(+1))
datetime.date(2003, 9, 24)

跟随 ISO year week number notation 找到1997年第15周的第一天。

>>> datetime(1997,1,1)+relativedelta(day=4, weekday=MO(-1), weeks=+14)
datetime.datetime(1997, 4, 7, 0, 0)

千年变了多久了?

>>> relativedelta(NOW, date(2001,1,1))
relativedelta(years=+2, months=+8, days=+16,
              hours=+20, minutes=+54, seconds=+47, microseconds=+282310)

约翰多大了?

>>> johnbirthday = datetime(1978, 4, 5, 12, 0)
>>> relativedelta(NOW, johnbirthday)
relativedelta(years=+25, months=+5, days=+12,
          hours=+8, minutes=+54, seconds=+47, microseconds=+282310)

它也适用于约会。

>>> relativedelta(TODAY, johnbirthday)
relativedelta(years=+25, months=+5, days=+11, hours=+12)

使用年份获取今天的日期:

>>> date(2003, 1, 1)+relativedelta(yearday=260)
datetime.date(2003, 9, 17)

我们可以使用今天的日期,因为在给定的年份中,yearday应该是绝对的:

>>> TODAY+relativedelta(yearday=260)
datetime.date(2003, 9, 17)

去年应该是同一天:

>>> date(2002, 1, 1)+relativedelta(yearday=260)
datetime.date(2002, 9, 17)

但不是闰年:

>>> date(2000, 1, 1)+relativedelta(yearday=260)
datetime.date(2000, 9, 16)

我们可以用非闰年来忽略这一点:

>>> date(2000, 1, 1)+relativedelta(nlyearday=260)
datetime.date(2000, 9, 17)