4

I would like to measure the execution time of some piece of code in days, hours, minutes and seconds. This is what I have so far:

import time
start_time = time.time()

# some code

elapsed = time.strftime("%H:%M:%S", time.gmtime(time.time() - start_time))
print(f"Took: {elapsed}")

The problem is that if the code that I am measuring takes longer than 24h, the time displayed overflows and starts from zero again. I would like something like this:

# Example: 12 hours and 34 minutes should be printed as 
> Took: 12:34:00

# Example: 26 hours and 3 minutes should be printed as 
> Took: 1:02:03:00
r0f1
  • 2,717
  • 3
  • 26
  • 39
  • 1
    From a programmer's perspective, having a consistent way to parse the data is preferable. I would prefer to see all "Took X amount of time" to be in seconds or milliseconds. Then it's a lot easier to grep/parse/compare. For your problem, I really like Arrow's humanize function: https://arrow.readthedocs.io/en/latest/#humanize – Robert Seaman Jun 04 '20 at 15:19

5 Answers5

6

You could use datetime:

from datetime import datetime as dt

start = dt.fromtimestamp(1588432670)
end = dt.now()
elapsed=end-start
print("Took: %02d:%02d:%02d:%02d" % (elapsed.days, elapsed.seconds // 3600, elapsed.seconds // 60 % 60, elapsed.seconds % 60))

Output:

Took: 33:00:21:49
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47
  • When do you use datetime vs time module? – Eddie Aug 12 '22 at 20:00
  • 1
    @Eddie The time module is principally for working with Unix time stamps; expressed as a floating point number taken to be seconds since the Unix epoch. The datetime module can support many of the same operations, but provides a more object oriented set of types, and also has some limited support for time zones. https://stackoverflow.com/q/7479777/603136 – samwyse Dec 06 '22 at 15:22
4

The result of time.gmtime(time.time() - start_time) is not what you seem to think it is. Instead of being a duration of time it is a point in time. Let me explain.

The result of time.time() is the number of seconds since January 1, 1970, 00:00:00 (UTC) at the time of calling. Therefore, the statement time.time() - start_time will produce the number of seconds between the two calls. So far so good. However, the time.gmtime function is interpreting this duration as the number of seconds since January 1, 1970, 00:00:00 (UTC) and formatting the time accordingly. What you are seeing then is the time portion of the date January 1, 1970, 12:34:00 (UTC).

I suggest you either use the datetime.timedelta object and format using that, or as others have suggested, output the duration in seconds or milliseconds.

If you want to format this number yourself, you could use something like this:

def format_duration(duration):
    mapping = [
        ('s', 60),
        ('m', 60),
        ('h', 24),
    ]
    duration = int(duration)
    result = []
    for symbol, max_amount in mapping:
        amount = duration % max_amount
        result.append(f'{amount}{symbol}')
        duration //= max_amount
        if duration == 0:
            break

    if duration:
        result.append(f'{duration}d')

    return ' '.join(reversed(result))
Kendas
  • 1,963
  • 13
  • 20
3

You should try this:

import time
start_time = time.time()
...
elapsed_time = time.time() - start_time
days = 0
if elapsed_time >= 86400:
    days = int(elapsed_time / 86400)
elapsed = time.strftime("%H:%M:%S", time.gmtime(time.time() - start_time))
if days == 0:
    print(f"Took: {elapsed}")
else:
    print(f"Took: {days}:{eplased}")

  
Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
Metalgear
  • 3,391
  • 1
  • 7
  • 16
2

Try using timeit:

import timeit
timeit.timeit(<callable function>, number = 100)

Here timeit will call callable function number times and give you the average runtime.

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
lorem_bacon
  • 165
  • 1
  • 10
2

Time types can only include hours and less units. You should use datetime instead of time as follows:

from datetime import datetime
start_time = datetime.now()

# some code

elapsed = datetime.now() - start_time)
print(f"Took: {elapsed}")

Example usage of Datetime:

from datetime import datetime
d1 = datetime(2013,9,1,5,5,4)
d2 = datetime(2013,1,13,3,2,1)
result1 = d1-d2
print ('{} between {} and {}'.format(result1, d1, d2))

This produces following output:

231 days, 2:03:03 between 2013-09-01 05:05:04 and 2013-01-13 03:02:01
Hamza
  • 5,373
  • 3
  • 28
  • 43