Convert seconds to hh:mm:ss in Python

PythonDjangoTime

Python Problem Overview


How do I convert an int (number of seconds) to the formats mm:ss or hh:mm:ss?

I need to do this with Python code (and if possible in a Django template).

Python Solutions


Solution 1 - Python

I can't believe any of the many answers gives what I'd consider the "one obvious way to do it" (and I'm not even Dutch...!-) -- up to just below 24 hours' worth of seconds (86399 seconds, specifically):

>>> import time
>>> time.strftime('%H:%M:%S', time.gmtime(12345))
'03:25:45'

Doing it in a Django template's more finicky, since the time filter supports a funky time-formatting syntax (inspired, I believe, from PHP), and also needs the datetime module, and a timezone implementation such as pytz, to prep the data. For example:

>>> from django import template as tt
>>> import pytz
>>> import datetime
>>> tt.Template('{{ x|time:"H:i:s" }}').render(
...     tt.Context({'x': datetime.datetime.fromtimestamp(12345, pytz.utc)}))
u'03:25:45'

Depending on your exact needs, it might be more convenient to define a custom filter for this formatting task in your app.

Solution 2 - Python

>>> a = datetime.timedelta(seconds=65)
datetime.timedelta(0, 65)
>>> str(a)
'0:01:05'

Solution 3 - Python

Read up on the datetime module.

SilentGhost's answer has the details my answer leaves out and is reposted here:

>>> a = datetime.timedelta(seconds=65)
datetime.timedelta(0, 65)
>>> str(a)
'0:01:05'

Solution 4 - Python

Code that does what was requested, with examples, and showing how cases he didn't specify are handled:

def format_seconds_to_hhmmss(seconds):
    hours = seconds // (60*60)
    seconds %= (60*60)
    minutes = seconds // 60
    seconds %= 60
    return "%02i:%02i:%02i" % (hours, minutes, seconds)

def format_seconds_to_mmss(seconds):
    minutes = seconds // 60
    seconds %= 60
    return "%02i:%02i" % (minutes, seconds)

minutes = 60
hours = 60*60
assert format_seconds_to_mmss(7*minutes + 30) == "07:30"
assert format_seconds_to_mmss(15*minutes + 30) == "15:30"
assert format_seconds_to_mmss(1000*minutes + 30) == "1000:30"

assert format_seconds_to_hhmmss(2*hours + 15*minutes + 30) == "02:15:30"
assert format_seconds_to_hhmmss(11*hours + 15*minutes + 30) == "11:15:30"
assert format_seconds_to_hhmmss(99*hours + 15*minutes + 30) == "99:15:30"
assert format_seconds_to_hhmmss(500*hours + 15*minutes + 30) == "500:15:30"

You can--and probably should--store this as a timedelta rather than an int, but that's a separate issue and timedelta doesn't actually make this particular task any easier.

Solution 5 - Python

You can calculate the number of minutes and hours from the number of seconds by simple division:

seconds = 12345
minutes = seconds // 60
hours = minutes // 60

print "%02d:%02d:%02d" % (hours, minutes % 60, seconds % 60)
print "%02d:%02d" % (minutes, seconds % 60)

Here // is Python's integer division.

Solution 6 - Python

If you use divmod, you are immune to different flavors of integer division:

# show time strings for 3800 seconds

# easy way to get mm:ss
print "%02d:%02d" % divmod(3800, 60)

# easy way to get hh:mm:ss
print "%02d:%02d:%02d" % \
    reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
        [(3800,),60,60])


# function to convert floating point number of seconds to
# hh:mm:ss.sss
def secondsToStr(t):
    return "%02d:%02d:%02d.%03d" % \
        reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
            [(round(t*1000),),1000,60,60])

print secondsToStr(3800.123)

Prints:

63:20
01:03:20
01:03:20.123

Solution 7 - Python

Not being a Python person, but the easiest without any libraries is just:

total   = 3800
seconds = total % 60
total   = total - seconds
hours   = total / 3600
total   = total - (hours * 3600)
mins    = total / 60

Solution 8 - Python

Just be careful when dividing by 60: division between integers returns an integer -> 12/60 = 0 unless you import division from future. The following is copy and pasted from Python 2.6.2:

IDLE 2.6.2      
>>> 12/60
0
>>> from __future__ import division
>>> 12/60
0.20000000000000001

Solution 9 - Python

If you need to do this a lot, you can precalculate all possible strings for number of seconds in a day:

try:
    from itertools import product
except ImportError:
    def product(*seqs):
        if len(seqs) == 1:
            for p in seqs[0]:
                yield p,
        else:
            for s in seqs[0]:
                for p in product(*seqs[1:]):
                    yield (s,) + p

hhmmss = []
for (h, m, s) in product(range(24), range(60), range(60)):
    hhmmss.append("%02d:%02d:%02d" % (h, m, s))

Now conversion of seconds to format string is a fast indexed lookup:

print hhmmss[12345]

prints

'03:25:45'

EDIT:

Updated to 2020, removing Py2 compatibility ugliness, and f-strings!

import sys
from itertools import product


hhmmss = [f"{h:02d}:{m:02d}:{s:02d}"
             for h, m, s in product(range(24), range(60), range(60))]

# we can still just index into the list, but define as a function
# for common API with code below
seconds_to_str = hhmmss.__getitem__

print(seconds_to_str(12345))

How much memory does this take? sys.getsizeof of a list won't do, since it will just give us the size of the list and its str refs, but not include the memory of the strs themselves:

# how big is a list of 24*60*60 8-character strs?
list_size = sys.getsizeof(hhmmss) + sum(sys.getsizeof(s) for s in hhmmss)
print("{:,}".format(list_size))

prints:

5,657,616

What if we just had one big str? Every value is exactly 8 characters long, so we can slice into this str and get the correct str for second X of the day:

hhmmss_str = ''.join([f"{h:02d}:{m:02d}:{s:02d}"
                      for h, m, s in product(range(24),
                                             range(60),
                                             range(60))])
def seconds_to_str(n):
    loc = n * 8
    return hhmmss_str[loc: loc+8]

print(seconds_to_str(12345))

Did that save any space?

# how big is a str of 24*60*60*8 characters?
str_size = sys.getsizeof(hhmmss_str)
print("{:,}".format(str_size))

prints:

691,249

Reduced to about this much:

print(str_size / list_size)

prints:

0.12218026108523448

On the performance side, this looks like a classic memory vs. CPU tradeoff:

import timeit

print("\nindex into pre-calculated list")
print(timeit.timeit("hhmmss[6]", '''from itertools import product; hhmmss = [f"{h:02d}:{m:02d}:{s:02d}"
                     for h, m, s in product(range(24),
                                             range(60),
                                             range(60))]'''))
print("\nget slice from pre-calculated str")
print(timeit.timeit("hhmmss_str[6*8:7*8]", '''from itertools import product; hhmmss_str=''.join([f"{h:02d}:{m:02d}:{s:02d}"
                     for h, m, s in product(range(24),
                                             range(60),
                                             range(60))])'''))

print("\nuse datetime.timedelta from stdlib")
print(timeit.timeit("timedelta(seconds=6)", "from datetime import timedelta"))
print("\ninline compute of h, m, s using divmod")
print(timeit.timeit("n=6;m,s=divmod(n,60);h,m=divmod(m,60);f'{h:02d}:{m:02d}:{s:02d}'"))

On my machine I get:

index into pre-calculated list
0.0434853

get slice from pre-calculated str
0.1085147

use datetime.timedelta from stdlib
0.7625738

inline compute of h, m, s using divmod
2.0477764

Solution 10 - Python

Besides the fact that Python has built in support for dates and times (see bigmattyh's response), finding minutes or hours from seconds is easy:

minutes = seconds / 60
hours = minutes / 60

Now, when you want to display minutes or seconds, MOD them by 60 so that they will not be larger than 59

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser166648View Question on Stackoverflow
Solution 1 - PythonAlex MartelliView Answer on Stackoverflow
Solution 2 - PythonSilentGhostView Answer on Stackoverflow
Solution 3 - PythonMatt HowellView Answer on Stackoverflow
Solution 4 - PythonGlenn MaynardView Answer on Stackoverflow
Solution 5 - PythonsthView Answer on Stackoverflow
Solution 6 - PythonPaulMcGView Answer on Stackoverflow
Solution 7 - PythongaqziView Answer on Stackoverflow
Solution 8 - PythonFrancescoView Answer on Stackoverflow
Solution 9 - PythonPaulMcGView Answer on Stackoverflow
Solution 10 - PythonEd S.View Answer on Stackoverflow