1

I have a a date in strptime that I want to show as 'X hours ago'. I can happily convert hours into days and weeks etc. but I don't know how to do the initial sum. Here is how I'm converting the string into strptime:

time.strptime(obj.created_at, '%a %b %d %H:%M:%S +0000 %Y')

p.s. bonus points for figuring out why it won't take %z for '+0000' - am I completely wrong about what this is?

chrism
  • 2,905
  • 8
  • 37
  • 40
  • This must be one of the most common questions on SO. – Jonas Elfström Oct 15 '09 at 09:36
  • 1
    I would appreciate being pointed to an example where it has already been answered in that case – chrism Oct 15 '09 at 09:42
  • I think the hint was that you could search (at the top of the page) for previous similar questions and see their answers. – pavium Oct 15 '09 at 09:45
  • got the hint, took the hint and found nothing that either fitted my problem or nothing that was suitably simple enough for me to understand – chrism Oct 15 '09 at 09:50
  • 2
    Duplicate: http://stackoverflow.com/questions/410221/natural-relative-days-in-python, http://stackoverflow.com/questions/1551382/python-user-friendly-time-format, http://stackoverflow.com/questions/1096396/what-is-the-easiest-way-to-handle-dates-times-in-python, etc. There are dozens. – S.Lott Oct 15 '09 at 10:16
  • @chrism: If none of the other question fit your problem, please provide details showing the other questions and what's different about your question. – S.Lott Oct 15 '09 at 11:30

3 Answers3

4

It seems the timesince in Django could help you out without you having to convert. The source for timesince is available here.

Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
Jonas Elfström
  • 30,834
  • 6
  • 70
  • 106
2

The datetime module is definitely easier to use, but, if you insist, you can do it with the time module instead. I.e.:

>>> import time
>>> fmt = '%a %b %d %H:%M:%S +0000 %Y'
>>> time.strftime(fmt)
'Thu Oct 15 07:54:07 +0000 2009'
>>> createdat = 'Thu Oct 15 02:30:30 +0000 2009'
>>> createdtim = time.strptime(createdat, fmt)
>>> hoursago = (time.time() - time.mktime(createdtim)) / 3600
>>> print hoursago
5.42057559947

One reason the time module is so pesky to use is that it uses two different ways to represent time -- one is a 9-tuple (and that's what you get from strptime), and one is a float "seconds since the epoch" (and that's what you need to do differences); the mktime function translates the former to the latter. Difference in hours is clearly 1/3600 of the difference in seconds -- you'll have to decide how to display a typically-fractionary "number of hours ago", of course (hour and fraction with some digits, or, round to closest integer number of hours, or what else).

The literal '+0000' in your format, for strptime, means you expect and ignore those literal characters at that spot in your "createdat" string (normally you'd have a timezone offset specifier there). If that's indeed what you want, then you have the right format string!

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
0

Can you use datetime instead? (Or convert whatever you have into datetime?)

>>> import datetime
>>> created_at = datetime.datetime(2009,10,15, 13)
>>> now = datetime.datetime.now()
>>> delta = now - created_at
>>> hours_ago = '%d Hours Ago' % (delta.seconds/60/60)
>>> hours_ago
'5 Hours Ago'
monkut
  • 42,176
  • 24
  • 124
  • 155
  • I think I'm going to need to read up about datetime, for a rookie it's a bit of a mind bender, and not something that I can just borrow from an example – chrism Oct 15 '09 at 10:08
  • datetime makes dates/times much more manageable, I rarely find myself using time. – monkut Oct 15 '09 at 10:41
  • The code is just subtracting the created_at time from the time now, so that we have delta.seconds ago, then changing delta.seconds to hours by dividing by secs/min and min/hour. – foosion Oct 15 '09 at 11:24