I have a function that returns information in seconds, but I need to store that information in hours:minutes:seconds.
Is there an easy way to convert the seconds to this format in Python?
This question is related to
python
This is my quick trick:
from humanfriendly import format_timespan
secondsPassed = 1302
format_timespan(secondsPassed)
# '21 minutes and 42 seconds'
For more info Visit: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan
If you need to get datetime.time
value, you can use this trick:
my_time = (datetime(1970,1,1) + timedelta(seconds=my_seconds)).time()
You cannot add timedelta
to time
, but can add it to datetime
.
UPD: Yet another variation of the same technique:
my_time = (datetime.fromordinal(1) + timedelta(seconds=my_seconds)).time()
Instead of 1
you can use any number greater than 0. Here we use the fact that datetime.fromordinal
will always return datetime
object with time
component being zero.
You can divide seconds by 60 to get the minutes
import time
seconds = time.time()
minutes = seconds / 60
print(minutes)
When you divide it by 60 again, you will get the hours
The solutions above will work if you're looking to convert a single value for "seconds since midnight" on a date to a datetime object or a string with HH:MM:SS, but I landed on this page because I wanted to do this on a whole dataframe column in pandas. If anyone else is wondering how to do this for more than a single value at a time, what ended up working for me was:
mydate='2015-03-01'
df['datetime'] = datetime.datetime(mydate) + \
pandas.to_timedelta(df['seconds_since_midnight'], 's')
In my case I wanted to achieve format "HH:MM:SS.fff". I solved it like this:
timestamp = 28.97000002861023
str(datetime.fromtimestamp(timestamp)+timedelta(hours=-1)).split(' ')[1][:12]
'00:00:28.970'
I can hardly name that an easy way (at least I can't remember the syntax), but it is possible to use time.strftime, which gives more control over formatting:
from time import strftime
from time import gmtime
strftime("%H:%M:%S", gmtime(666))
'00:11:06'
strftime("%H:%M:%S", gmtime(60*60*24))
'00:00:00'
gmtime is used to convert seconds to special tuple format that strftime()
requires.
Note: Truncates after 23:59:59
hours (h) calculated by floor division (by //) of seconds by 3600 (60 min/hr * 60 sec/min)
minutes (m) calculated by floor division of remaining seconds (remainder from hour calculation, by %) by 60 (60 sec/min)
similarly, seconds (s) by remainder of hour and minutes calculation.
Rest is just string formatting!
def hms(seconds):
h = seconds // 3600
m = seconds % 3600 // 60
s = seconds % 3600 % 60
return '{:02d}:{:02d}:{:02d}'.format(h, m, s)
print(hms(7500)) # Should print 02h05m00s
dateutil.relativedelta
is convenient if you need to access hours, minutes and seconds as floats as well. datetime.timedelta
does not provide a similar interface.
from dateutil.relativedelta import relativedelta
rt = relativedelta(seconds=5440)
print(rt.seconds)
print('{:02d}:{:02d}:{:02d}'.format(
int(rt.hours), int(rt.minutes), int(rt.seconds)))
Prints
40.0
01:30:40
datetime
:':0>8'
format:from datetime import timedelta
"{:0>8}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'
"{:0>8}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'
"{:0>8}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'
':0>8'
format:"{}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'
"{}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'
"{}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'
time
:from time import gmtime
from time import strftime
# NOTE: The following resets if it goes over 23:59:59!
strftime("%H:%M:%S", gmtime(125))
# Result: '00:02:05'
strftime("%H:%M:%S", gmtime(60*60*24-1))
# Result: '23:59:59'
strftime("%H:%M:%S", gmtime(60*60*24))
# Result: '00:00:00'
strftime("%H:%M:%S", gmtime(666777))
# Result: '17:12:57'
# Wrong
division = 3623 // 3600 #to hours
division2 = 600 // 60 #to minutes
print (division) #write hours
print (division2) #write minutes
PS My code is unprofessional
This is how I got it.
def sec2time(sec, n_msec=3):
''' Convert seconds to 'D days, HH:MM:SS.FFF' '''
if hasattr(sec,'__len__'):
return [sec2time(s) for s in sec]
m, s = divmod(sec, 60)
h, m = divmod(m, 60)
d, h = divmod(h, 24)
if n_msec > 0:
pattern = '%%02d:%%02d:%%0%d.%df' % (n_msec+3, n_msec)
else:
pattern = r'%02d:%02d:%02d'
if d == 0:
return pattern % (h, m, s)
return ('%d days, ' + pattern) % (d, h, m, s)
Some examples:
$ sec2time(10, 3)
Out: '00:00:10.000'
$ sec2time(1234567.8910, 0)
Out: '14 days, 06:56:07'
$ sec2time(1234567.8910, 4)
Out: '14 days, 06:56:07.8910'
$ sec2time([12, 345678.9], 3)
Out: ['00:00:12.000', '4 days, 00:01:18.900']
By using the divmod()
function, which does only a single division to produce both the quotient and the remainder, you can have the result very quickly with only two mathematical operations:
m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
And then use string formatting to convert the result into your desired output:
print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+
The following set worked for me.
def sec_to_hours(seconds):
a=str(seconds//3600)
b=str((seconds%3600)//60)
c=str((seconds%3600)%60)
d=["{} hours {} mins {} seconds".format(a, b, c)]
return d
print(sec_to_hours(10000))
# ['2 hours 46 mins 40 seconds']
print(sec_to_hours(60*60*24+105))
# ['24 hours 1 mins 45 seconds']
Source: Stackoverflow.com