Django: How to get a time difference from the time post?
Solution 1
Your code is already working; a datetime.timedelta
object is returned.
To get the total number of seconds instead, you need to call the .total_seconds()
method on the resulting timedelta
:
from django.utils.timezone import utc
def get_time_diff(self):
if self.time_posted:
now = datetime.datetime.utcnow().replace(tzinfo=utc)
timediff = now - self.time_posted
return timediff.total_seconds()
.total_seconds()
returns a float
value, including microseconds.
Note that you need to use a timezone aware datetime
object, since the Django DateTimeField
handles timezone aware datetime
objects as well. See Django Timezones documentation.
Demonstration of .total_seconds()
(with naive datetime
objects, but the principles are the same):
>>> import datetime
>>> time_posted = datetime.datetime(2013, 3, 31, 12, 55, 10)
>>> timediff = datetime.datetime.now() - time_posted
>>> timediff.total_seconds()
1304529.299168
Because both objects are timezone aware (have a .tzinfo
attribute that is not None
), calculations between them take care of timezones and subtracting one from the other will do the right thing when it comes to taking into account the timezones of either object.
Solution 2
Assuming you are doing this within a template, you can also use the timesince template tag.
For example:
{{ blog_date|timesince:comment_date }}
Solution 3
Your code
timediff = datetime.datetime.now() - self.pub_date
should work to get the time difference. However, this returns timedelta
object. To get difference in seconds you use .seconds
attribute
timediff = datetime.datetime.now() - self.pub_date
timediff.seconds # difference in seconds.
Related videos on Youtube
Comments
-
Bob Fang about 2 years
Say I have a class in model
class Post(models.Model): time_posted = models.DateTimeField(auto_now_add=True, blank=True) def get_time_diff(self): timediff = timediff = datetime.datetime.now() - self.time_posted print timediff # this line is never executed return timediff
I defined a get_time_diff to get the time difference from the time when the Post is posted up to now, according to the document, the DateTimeField should be able to be converted to datetime automatically, is that correct? Why the print statement is never being run? How can you extract the time difference?
Beside, if you get a time difference, is there an easy way to convert the time difference to an integer, like the number of seconds of the total time.
-
ryechus over 9 yearsThis is old, but I noticed no one answered your question about print. Your print statement probably is working, but you won't see it in on your site. print only works in the console. If you have a look at your logs you will find your print message.
-
-
Aya about 11 yearsI don't think that will work if the difference is more than one day.
-
Rohan about 11 years@Aya, I think it will. Do you know why it won't?
-
Aya about 11 yearsWell, the docs say that the
seconds
attribute is "Between 0 and 86399 inclusive". -
Bob Fang about 11 yearsThanks first but in my case the time_posted is a DateTimeField. I tried, it does not work.
-
Martijn Pieters about 11 years@dorafmon: in your custom model method
self.time_posted
returns adatetime
instance, see Model Methods. -
Aya about 11 years@dorafmon ...although the
blank=True
suggests you might not get a validdatetime
back, so you may have to check its validity before doing the subtraction. -
Martijn Pieters about 11 years@Aya: Interesting, mussed the
blank=True
there. Added anif
statement, nowget_time_diff
will returnNone
ifself.time_posted
is not defined. -
Bob Fang about 11 years@MartijnPieters but how can you convert the DatetimeField into a datetime? I got confused here actually.
-
Martijn Pieters about 11 years@dorafmon: It has already been converted. See the documentation I linked you to; the example there uses a
DateField
instead but the principle is the same. -
Martijn Pieters about 11 years@Rohan: There is a separate
.days
attribute..seconds
only contains the remainder; an event 10 days and 534 seconds age has a.seconds
attribute with534
, and it's.days
attribute will be10
. Use.total_seconds()
to turn that into a seconds-only value. -
Bob Fang about 11 years@MartijnPieters Sorry, I might be a little dump here, but since a DataTimeField can be converted to datatime automatically, why I cannot simply do
datetime.datetime.now()-self.time_posted
. -
Martijn Pieters about 11 years@dorafmon: How are you calling the
.get_time_diff()
method? What error do you see when you call it? You need to tell us more about what problems you are experiencing. When you have aPost
result object, calling.get_time_diff()
Just Works. -
Bob Fang about 11 years@MartijnPieters There is no error message, but using the code in the question up there. the print function is never executed, Also this function does not returen anything at all.
-
Martijn Pieters about 11 years@dorafmon: clearly you are not calling the code you think you are calling; there either will be a return value (at the very least
None
) or there will be an exception. -
Bob Fang about 11 years
-
aorcsik over 10 years@MartijnPieters I had to add a line to the answer, since I still needed to read through your full chat to understand my error.
-
Martijn Pieters over 10 years@aorcsik:
utcnow()
is not timezone aware either, but relies on your OS instead to tell it what the current UTC time is. The OS is timezone aware, but the resultingdatetime.datetime
object is not. -
Martijn Pieters over 10 years@aorcsik: As such, I had to roll back your edit as it was incorrect. Only attaching a timezone object to a
datetime.datetime
object makes it timezone-aware. -
aorcsik over 10 years@MartijnPieters right, right... just figured, sry. I get the time zone from the datetime from the database and set it to the now datetime, is that correct?
-
Martijn Pieters over 10 years@aorcsik: it is the
.replace(tzinfo=utc)
method call that returns a newdatetime.datetime()
instance with a timezone object attached; that is the timezone-aware object. -
Martijn Pieters over 10 years@aorcsik: No, just stick to UTC; because both the
now
object andself.time_posted
are fully timezone aware, the result is always going to be accurate. Thedatetime.datetime()
objects take care of handling the timezone details for you. -
Martijn Pieters over 10 years@aorcsik: By sticking to UTC you save yourself all those headaches.
-
aorcsik over 10 years@MartijnPieters yes, thank you very much! Could you please add these to the answer, maybe it will make others life easier next time :)
-
Programmer Gaurav almost 4 yearsBest Answer Thank you
-
rayon about 3 yearsThanks! Any idea of how to get the resulting duration in seconds?