相对增量

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类型旨在应用于现有的DateTime,可以替换该DateTime的特定组件,或表示时间间隔。

它是基于M.-A.Lemburg在他的 mx.DateTime 分机。但是,请注意,此类型 NOT 实现与他的工作相同的算法。做 NOT 期望它的行为像mx.DateTime的对应物。

构建相对DELTA实例有两种不同的方法。第一个是向它传递两个日期/日期时间类::

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添加到DateTime时考虑的属性顺序为:

  1. 月份

  2. 小时数

  3. 分钟数

  4. 微秒

最后,使用上述规则应用WEEKDAY。

例如

>>> 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)
返回:

返回一个 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(2003,1,30)+relativedelta(months=+1)
datetime.date(2003, 2, 28)
>>> date(2003,5,31)+relativedelta(months=-1)
datetime.date(2003, 4, 30)
>>> 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)