# Getting human-readable time interval strings

Here’s a neat little problem that came up yesterday. We’ve got some code using this common idiom to time a function call:

```start_time = time.time()
do_something_long_running()
end_time = time.time()

print "It took {} seconds to execute this".format(end_time - start_time)
```

We want to make the elapsed time in seconds more human-readable. The first thing we can do is use the string-format mini language to round the number to two decimal points:

```start_time = time.time()
do_something_long_running()
end_time = time.time()

print "It took {:.2f} seconds to execute this".format(end_time - start_time)
```

This is better! But for values that last longer than a few minutes, just displaying seconds is not particularly human friendly. What about minutes?

```start_time = time.time()
do_something_long_running()
end_time = time.time()
print "It took {} minutes to execute this".format((end_time - start_time) / 60.)

```

Well now we’ve just pushed the problem out to the next unit mark. So how about hours?

```start_time = time.time()
do_something_long_running()
end_time = time.time()

print "It took {} hours to execute this".format((end_time - start_time) / 3600.)
```

Great! But for function calls that cost in the range of a few seconds to a few minutes, all the significant digits get swallowed up in the rounding to hours. What we want is a nice, constant, `H:MM:SS.SS` format that can be easy to search against in log files and gives human-friendly reading. Similar to what we do above with dividing seconds by 60 to get minutes, and by 3600 (60 * 60) to get hours, we can write a function that does it all for us. We need to do an extra trick with the modulo operator, but otherwise this is straightforward:

```def hms_string(sec_elapsed):
h = int(sec_elapsed / (60 * 60))
m = int((sec_elapsed % (60 * 60)) / 60)
s = sec_elapsed % 60.
return "{}:{:>02}:{:>05.2f}".format(h, m, s)
# End hms_string

start_time = time.time()
do_something_long_running()
end_time = time.time()
print "It took {} to execute this".format(hms_string(end_time - start_time))
```

And the hms_string function could work with a `datetime.timedelta` as well, just pass in `timedelta.total_seconds()` as the value to `hms_string`:

```start_time = datetime.datetime.now()
do_something_long_running()
end_time = datetime.datetime.now()
seconds_elapsed = (end_time - start_time).total_seconds()
print "It took {} to execute this".format(hms_string(seconds_elapsed))
```

I recommend you check out the string format mini-language’s documentation — you can do all sorts of interesting things with it.

Using the source provided in this Python script, one can determine the bounding box, in inches, of a string as it would be rendered in a specific typeface and size on Windows. This, in turn, is useful in determining the estimated size of a text element in a text element exported using `arcpy.mapping` from an MXD given a custom string.