1

I have some trouble to understand the behavior of dateutil.relativedelta. I understand that relativedelta could return past dates if I use negative arguments as specified in relativedelta doc.

However, when I provide positive parameters, I expect that it always return a date in the future... that seems legit right?

My use case is the following : we are Tuesday, it is 8:35. I want to get the date of the closest Monday and Tuesday at 6:00.

Here what I did. The first result seems correct to me, while the second one is wrong.

>>> import datetime
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2016, 11, 29, 8, 35, 23, 786349)

>>> from dateutil import relativedelta
>>> now.weekday()
1

>>> now + relativedelta.relativedelta(weekday=0, hour=6, minute=0) # should give a time in the future
datetime.datetime(2016, 12, 5, 6, 0, 23, 786349)  # here this is correct, in the future

>>> now + relativedelta.relativedelta(weekday=1, hour=6, minute=0) # should give a time in the future
datetime.datetime(2016, 11, 29, 6, 0, 23, 786349)  # but this is in the past / I would expect result (2016, 12, 6, 6, 0, 23, 786349)

So , am I doing something wrong here ?

Tanzaho
  • 1,362
  • 12
  • 20

2 Answers2

3

So according to your initial date, you're actually at 8AM, but you're targeting 6AM by using the hour param, if you're trying to increment one hour, you should use hours and minutes respectively

>>> now
datetime.datetime(2016, 11, 29, 3, 5, 41, 763818)

>>> now.weekday()
1

>>> now + relativedelta.relativedelta(weekday=1, hour=1)
datetime.datetime(2016, 11, 29, 1, 5, 41, 763818) # Notice how it's in the past

>>> now + relativedelta.relativedelta(weekday=1, hours=1)
datetime.datetime(2016, 11, 29, 4, 5, 41, 763818) # Notice how it's one hour in the future

>>> n + relativedelta.relativedelta(weekday=1, hour=6, minute=0, weeks=1)
datetime.datetime(2016, 12, 6, 6, 0, 41, 763818)
Bryan
  • 6,682
  • 2
  • 17
  • 21
  • Thanks for your answer Bryan, but the result is not the one I expect (next Tuesday, aka 2016 Dec. 6th). What you did here was to 'add' one hour to the current time. But I want the next 'available' Tuesday at a given hour. – Tanzaho Nov 29 '16 at 08:13
  • Does using weeks=1 get you to where you're looking for? ```now + relativedelta.relativedelta(weekday=1, hours=1, weeks=1)``` – Bryan Nov 29 '16 at 08:15
  • Yes, that fixes my first example, but breaks the second one (it gives a result too far in the future). – Tanzaho Nov 29 '16 at 08:21
  • Ok, so I think I misunderstood ya in the beginning, you're looking to be exactly at 6 on the dot, one week from now, as I updated at the end of the code in the answer. Is that correct? – Bryan Nov 29 '16 at 08:23
  • It works for the first example (weekday=1) but breaks on weekday=0 : >>> now + relativedelta.relativedelta(weekday=0, hour=6, minute=0, weeks=1) datetime.datetime(2016, 12, 12, 6, 0, 23, 786349) – Tanzaho Nov 29 '16 at 08:38
  • The first one should return datetime.datetime(2016, 12, 5, 6, 0, 23, 786349) ... Here, using `weeks` forces an additional timedelta. – Tanzaho Nov 29 '16 at 08:39
  • @Tanzaho Use `weekday=rrule.TU(+2)` for next Tuesday, I believe. Don't mess around with `weeks`. – Paul Nov 29 '16 at 11:32
2

I think it's in the doc:

Starting with, about weekday:

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.

So by passing 1, it's like you're passing (1, 1)

Then, continuing on the doc, on the 7th dot of behavior of operations with relativedelta:

Notice that if the calculated date is already Monday, for example, using (0, 1) or (0, -1) won’t change the day.

So the 29th of November is already a Tuesday, and you're asking for a Tuesday.

So nothing changes.

Twidi
  • 36
  • 4
  • You're correct, the seventh point explains it all. This is the behavior by design.Thanks for this input which explains everything. It was in the doc and I missed it. – Tanzaho Nov 29 '16 at 14:07
  • Actually, you're answer makes more sense and answers the question in my title. So I'm marking it as the accepted answer finally, event hough I'm using the trick from @Bryan answer. – Tanzaho Nov 29 '16 at 14:19