Reputation: 18007
Excerpt from the description of dateutil.relativedelta.relativedelta
,
year, month, day, hour, minute, second, microsecond:
Absolute information (argument is singular); adding or subtracting a relativedelta with absolute information does not perform an aritmetic 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 aritmetic operation on the original datetime value with the information in the relativedelta.
I can see the differences from the following example when it comes to adding and subtracting.
>>> from datetime import datetime
>>> from dateutil.relativedelta import relativedelta
>>> now = datetime.now()
>>> str(now)
'2016-05-23 22:32:48.427269'
>>> singular = relativedelta(month=3)
>>> plural = relativedelta(months=3)
# subtracting
>>> str(now - singular) # replace the corresponding value in the original datetime with the value(s) in relativedelta
'2016-03-23 22:32:48.427269'
>>> str(now - plural) # perform the corresponding aritmetic operation on the original datetime value with the information in the relativedelta.
'2016-02-23 22:32:48.427269'
# adding
>>> str(now + singular) # replace the corresponding value in the original datetime with the value(s) in relativedelta
'2016-03-23 22:32:48.427269'
>>> str(now + plural) # perform the corresponding aritmetic operation on the original datetime value with the information in the relativedelta.
'2016-08-23 22:32:48.427269'
Beside this, what are other differences between the singular and plural argument in relativedelta
?
Upvotes: 1
Views: 346
Reputation: 10863
Singular arguments are absolute information, essentially you can think of relativedelta(month=3)
to mean "the month of March, relative to whatever date and time it is applied to" (i.e. replace the month
keyword). This is not amenable to operations like multiplication and division, so these operations have no effect on absolute information:
>>> relativedelta.relativedelta(month=3) * 3
relativedelta(month=3)
Plural arguments are relative offsets, so they are saying, "give me this many months after/before the date". Since these are an offset, they are amenable to multiplication and division:
>>> relativedelta.relativedelta(months=3) * 3
relativedelta(months=9)
A good example of where this is used would be in the tzrange
class, which uses relativedelta
to emulate the behavior of POSIX-style TZ strings. You can see this test, which uses the following object:
tz.tzrange('EST', -18000, 'EDT', -14400,
start=relativedelta(hours=+2, month=4, day=1, weekday=SU(+1)),
end=relativedelta(hours=+1, month=10, day=31, weekday=SU(-1)))
This constructs a time zone equivalent to 'EST5EDT'
, where the start
relativedelta is added to any date in a given year to find the start of DST for that year, and end
is added to any date in a given year to find the end of DST for that year.
Breaking it down:
month
gives you a date in Aprilday
starts you out at the first of the monthweekday=SU(+1)
gives you the first Sunday on or after the specified date (this is applied after the month
and day
parameters, so when the day
is set to 1, you get the first Sunday of the month).hours=+2
- this will give you 2 hours after all the other stuff has been applied. Probably in this case hour=2
makes more sense for demonstrating the concept, though, since where these relativedelta
s actually gets used I think strips out the time portion first (giving a date at midnight), so this is really trying to encode 2AM.Upvotes: 1