24

I've spent the past hour digging around the Python docs and many SO questions; please forgive me for being another Python newbie trapped by the mystery of time difference in Python.

My goal is to determine the difference between the current time and a certain date/time regardless of being in the past/future and return a workable format such as seconds.

For example, if the inputs are 2:00PM and 4:00PM (now), I'd like it to say "-7200", representing the event occurred two hours AGO. If the inputs are Fri 4:00PM (now) and Sun 5:00PM the output should be "176400" seconds, representing two days and 1 hour from now.

Here are the things I've tried...

  • My first version was a function that took a string timestamp and pieced it to multiple variables, and then compared them. It was clunky with many errors and I imagine if I posted it here I would be responsible for a programmers throwing up.

  • I stumbled upon this magical timedelta function and explored the docs and SO, but I don't think it does what I'm looking for.

  • I had the idea to convert both timestamps into seconds since epoch and then subtract, but this becomes a problem if the subtraction is in the wrong order (different cases if the event is in the future), and I feel like adding if statements to check the sign of the seconds would be clunky and something to avoid.

This is my current code (still needs to be fixed for 'bi-directional' comparison), from a previously resolved SO question:

now = time.strftime("%a %b %d %H:%M:%S %Y")
then = time.ctime(os.path.getmtime("x.cache"))
tdelta = datetime.strptime(now, '%a %b %d %H:%M:%S %Y') - datetime.strptime(then, '%a %b %d %H:%M:%S %Y')

And I feel like I should somehow be able to pull seconds from this, like in this question: Python's timedelta: can't I just get in whatever time unit I want the value of the entire difference?

But I am at a lost on how to connect these dots.

How can I accomplish this?

Community
  • 1
  • 1
daltonf
  • 430
  • 1
  • 3
  • 8

3 Answers3

39

You should be able to use

tdelta.total_seconds()

to get the value you are looking for. This is because tdelta is a timedelta object, as is any difference between datetime objects.

A couple of notes:

  1. Using strftime followed by strptime is superfluous. You should be able to get the current datetime with datetime.now.
  2. Similarly, using time.ctime followed by strptime is more work than needed. You should be able to get the other datetime object with datetime.fromtimestamp.

So, your final code could be

now = datetime.now()
then = datetime.fromtimestamp(os.path.getmtime("x.cache"))
tdelta = now - then
seconds = tdelta.total_seconds()
George Stocker
  • 57,289
  • 29
  • 176
  • 237
murgatroid99
  • 19,007
  • 10
  • 60
  • 95
  • Awesome. Thank you so much for the explanation AND the confirmation of the final code! – daltonf Aug 26 '12 at 16:54
  • `seconds = (time.time() - os.path.getmtime("x.cache"))`. The code that uses `datetime.now()` might break around DST transitions. Use `datetime.utcnow()` and `datetime.utcfromtimestamp()` if you can't use `time.time()`. – jfs Nov 17 '13 at 19:25
11

What's wrong with this method?

>>> from datetime import datetime
>>> a = datetime.now()
>>> b = datetime.now() # after a few seconds
>>> delta = a-b
>>> delta.total_seconds()
-6.655989

Note that total_seconds is only available in Python 2.7 <, but per the documentation is:

Equivalent to (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 computed with true division enabled.

which yields the exact same result.

Yuval Adam
  • 161,610
  • 92
  • 305
  • 395
  • He seems to want to calculate the difference with an *arbitrary* time, not necessarily calculate a program's runtime. In other words, I don't think he wants to only calculate differences between times that occur during the execution of the program. – murgatroid99 Aug 26 '12 at 16:35
  • 1
    Very Simple - Exactly what I needed to compare 2 times. Worth noting that ```datetime.utcnow()``` might be better. – Dan O'Boyle Sep 23 '15 at 17:02
2

I had the same problem couple of months ago. What you are looking for is datetime.timedelta and datetime.datetime.fromtimestamp(). Here is an example for how to use them to fix your problem.

import datetime
import time
t1 = time.time()
#do something to kill time or get t2 from somewhere
a = [i for i in range(1000)]
t2 = time.time()
#get the difference as datetime.timedelta object
diff=(datetime.datetime.fromtimestamp(t1) - datetime.datetime.fromtimestamp(t2))
#diff is negative as t2 is in the future compared to t2
print('difference is {0} seconds'.format(abs(diff.total_seconds())))
jkdev
  • 11,360
  • 15
  • 54
  • 77
MHardy
  • 491
  • 3
  • 7
  • 17