2

I have a model Player which contains a DateTimeField called time_joined. I am trying to find the time elapsed since time_joined, so I do:

curr_time = datetime.now()
print(player.time_joined)
print(curr_time)
print(curr_time - player.time_joined)
print('done')

The output from this block of code is:

2015-08-22 20:51:02.965000+00:00
2015-08-29 10:07:35.933000

And then it stops outputting anything, for some reason that I don't understand.

Thanks in advance for any help!

elaid
  • 351
  • 1
  • 10

2 Answers2

2

This is happening because you are subtracting naive and aware datetimes.

From the tzinfo section:

An object of type time or datetime may be naive or aware. A datetime object d is aware if d.tzinfo is not None and d.tzinfo.utcoffset(d) does not return None. If d.tzinfo is None, or if d.tzinfo is not None but d.tzinfo.utcoffset(d) returns None, d is naive. A time object t is aware if t.tzinfo is not None and t.tzinfo.utcoffset(None) does not return None. Otherwise, t is naive.

You can't subtract aware and naive datetimes. You have to either change both to naive or both to aware datetime to perform subtraction.

Let us try to subtract aware and a naive datetimes in the shell and see the results.

In [10]: aware_datetime # an aware datetime having timezone info
Out[10]: datetime.datetime(2014, 8, 19, 23, 57, 56, tzinfo=<UTC>)

In [11]: current_naive_datetime = datetime.now()

In [12]: current_naive_datetime # naive datetime having no timezone info
Out[12]: datetime.datetime(2015, 8, 29, 20, 50, 2, 350872)

In [13]: print(current_naive_datetime - aware_datetime)
 ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-59-2b7ea8141c3e> in <module>()
----> 1 print(current_naive_datetime - aware_datetime)

TypeError: can't subtract offset-naive and offset-aware datetimes

Solution-1 : Convert aware datetime aware_datetime to naive datetime

To perform the subtraction, you can convert aware_datetime object to naive by replacing its tzinfo with None.

In [14]: my_naive_datetime = aware_datetime.replace(tzinfo=None)

In [15]: my_naive_datetime
Out[15]: datetime.datetime(2014, 8, 19, 23, 57, 56)

In [16]: print(current_naive_datetime - my_naive_datetime)
374 days, 20:52:06.350872

Solution-2: Convert naive datetime datetime.now() to aware datetime

In [17]: import pytz

In [18]: aware_current_datetime = datetime.now().replace(tzinfo=pytz.UTC)

In [19]: aware_current_datetime
Out[19]: datetime.datetime(2015, 8, 29, 21, 21, 44, 227886, tzinfo=<UTC>)

In [20]: print(aware_current_datetime - aware_datetime)
374 days, 21:23:48.227886

(I don't know as to why you are not getting an error as i am able to get an error on my machine.)

Rahul Gupta
  • 46,769
  • 10
  • 112
  • 126
0

I'm guessing this. Please comment for any details. Enjoy!!

import datetime
curr_time = datetime.datetime.now()
print curr_time
2015-08-29 10:22:57.878721

after few secs......

future_time = datetime.datetime.now()
print future_time
2015-08-29 10:23:55.188854

I hope this what you are trying to accomplish!!

print future_time-curr_time
0:00:57.310133
  • The problem is that I need to use the datetime from the Django model Player. I understand how to find the difference between two datetimes in general, but I need to know why it is not working in this specific situation. – elaid Aug 29 '15 at 14:36
  • Basically curr_time (which you defined) has not timezone info in it. But player.time_joined is a Django defined based on timezone. This is the source of conflict. –  Aug 29 '15 at 15:35
  • But how do I make curr_time have a timezone – elaid Aug 29 '15 at 15:36
  • Please follow these links below: 1. http://stackoverflow.com/questions/7065164/how-to-make-an-unaware-datetime-timezone-aware-in-python 2. http://stackoverflow.com/questions/4563272/how-to-convert-a-python-utc-datetime-to-a-local-datetime-using-only-python-stand 3. https://docs.python.org/2/library/datetime.html#datetime.datetime.utcnow –  Aug 29 '15 at 15:38