3

How can I convert a dateutil.relativedelta object to a datetime.timedelta object?

e.g.,

# pip install python-dateutil

from dateutil.relativedelta import relativedelta
from datetime import timedelta

rel_delta = relativedelta(months=-2)
# How can I convert rel_delta to a timedelta object so that I can call total_seconds() ?
time_delta = ???(rel_delta)  
time_delta.total_seconds()  # call the timedelta.total_seconds() method
Rob Bednark
  • 25,981
  • 23
  • 80
  • 125

3 Answers3

8

You can't, for one huge reason: They don't store the same information. datetime.timedelta only stores days, seconds, and milliseconds, whereas dateutil.relativedelta stores every single time component fed to it.

That dateutil.relativedelta does so is important for storing things such as a difference of 1 month, but since the length of a month can vary this means that there is no way at all to express the same thing in datetime.timedelta.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • Thanks @Ignacio_Vazquez-Abrams! Now I get it -- the relativedata object stores data that is used when doing arithmetic with a datetime object, so it needs to have the same data types as datetime object. – Rob Bednark Jan 04 '15 at 16:59
5

In case someone is looking to convert a relativedelta to a timedelta from a specific date, simply add and subtract the known time:

utcnow = datetime.utcnow()
rel_delta = relativedelta(months=-2)
time_delta = utcnow + rel_delta - utcnow  # e.g, datetime.timedelta(days=-62)

As a commenter points out, the resulting timedelta value will differ based on what month it is.

Braiam
  • 1
  • 11
  • 47
  • 78
Ben
  • 2,348
  • 1
  • 20
  • 23
  • 2
    This is not well-defined. Replace `datetime.utcnow()` with `datetime(2000, 1, 1)`, `datetime(2000, 2, 1)` and `datetime(2000, 3, 1)` respectively and you'll get three different answers. – Åsmund Dec 13 '16 at 12:21
0

Depending on why you want to call total_seconds, it may be possible to refactor your code to avoid the conversion altogether. For example, consider a check on whether or not a user is over 18 years old:

datetime.date.today() - user['dateOfBirth'] < datetime.timedelta(days=365*18)

This check is not a good idea, because the timedelta object does not account for things like leap years. It's tempting to rewrite as:

datetime.date.today() - user['dateOfBirth'] < dateutil.relativedelta.relativedelta(years=18)

which would require comparing a timedelta (LHS) to a relativedelta (RHS), or converting one to the other. However, you can refactor the check to avoid this conversion altogether:

user['dateOfBirth'] + dateutil.relativedelta.relativedelta(years=18) > datetime.date.today()
Craig Finch
  • 978
  • 7
  • 21