How do I convert datetime.timedelta to minutes, hours in Python?
I get a start_date like this:
from django.utils.timezone import utc
import datetime
start_date = datetime.datetime.utcnow().replace(tzinfo=utc)
end_date = datetime.datetime.utcnow().replace(tzinfo=utc)
duration = end_date - start_date
I get output like this:
datetime.timedelta(0, 5, 41038)
How do I convert this into normal time like the following?
10 minutes, 1 hour like this
There's no built-in formatter for timedelta
objects, but it's pretty easy to do it yourself:
days, seconds = duration.days, duration.seconds
hours = days * 24 + seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60
Or, equivalently, if you're in Python 2.7+ or 3.2+:
seconds = duration.total_seconds()
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60
Now you can print it however you want:
'{} minutes, {} hours'.format(minutes, hours)
For example:
def convert_timedelta(duration):
days, seconds = duration.days, duration.seconds
hours = days * 24 + seconds // 3600
minutes = (seconds % 3600) // 60
seconds = (seconds % 60)
return hours, minutes, seconds
td = datetime.timedelta(2, 7743, 12345)
hours, minutes, seconds = convert_timedelta(td)
print '{} minutes, {} hours'.format(minutes, hours)
This will print:
9 minutes, 50 hours
If you want to get "10 minutes, 1 hour" instead of "10 minutes, 1 hours", you need to do that manually too:
print '{} minute{}, {} hour{}'.format(minutes, 's' if minutes != 1 else '',
hours, 's' if minutes != 1 else '')
Or you may want to write an english_plural
function to do the 's'
bits for you, instead of repeating yourself.
From your comments, it sounds like you actually want to keep the days separate. That's even easier:
def convert_timedelta(duration):
days, seconds = duration.days, duration.seconds
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = (seconds % 60)
return days, hours, minutes, seconds
If you want to convert this to a single value to store in a database, then convert that single value back to format it, do this:
def dhms_to_seconds(days, hours, minutes, seconds):
return (((days * 24) + hours) * 60 + minutes) * 60 + seconds
def seconds_to_dhms(seconds):
days = seconds // (3600 * 24)
hours = (seconds // 3600) % 24
minutes = (seconds // 60) % 60
seconds = seconds % 60
return days, hours, minutes, seconds
So, putting it together:
def store_timedelta_in_database(thingy, duration):
seconds = dhms_to_seconds(*convert_timedelta(duration))
db.execute('INSERT INTO foo (thingy, duration) VALUES (?, ?)',
thingy, seconds)
db.commit()
def print_timedelta_from_database(thingy):
cur = db.execute('SELECT duration FROM foo WHERE thingy = ?', thingy)
seconds = int(cur.fetchone()[0])
days, hours, minutes, seconds = seconds_to_dhms(seconds)
print '{} took {} minutes, {} hours, {} days'.format(thingy, minutes, hours, days)
A datetime.timedelta
corresponds to the difference between two dates, not a date itself. It's only expressed in terms of days, seconds, and microseconds, since larger time units like months and years don't decompose cleanly (is 30 days 1 month or 0.9677 months?).
If you want to convert a timedelta
into hours and minutes, you can use the total_seconds()
method to get the total number of seconds and then do some math:
x = datetime.timedelta(1, 5, 41038) # Interval of 1 day and 5.41038 seconds
secs = x.total_seconds()
hours = int(secs / 3600)
minutes = int(secs / 60) % 60
There is no need for custom helper functions if all we need is to print the string of the form [D day[s], ][H]H:MM:SS[.UUUUUU]
. timedelta object supports str()
operation that will do this. It works even in Python 2.6.
>>> from datetime import timedelta
>>> timedelta(seconds=90136)
datetime.timedelta(1, 3736)
>>> str(timedelta(seconds=90136))
'1 day, 1:02:16'
I don't think it's a good idea to caculate yourself.
If you just want a pretty output, just covert it into str
with str()
function or directly print()
it.
And if there's further usage of the hours and minutes, you can parse it to datetime
object use datetime.strptime()
(and extract the time part with datetime.time()
mehtod), for example:
import datetime
delta = datetime.timedelta(seconds=10000)
time_obj = datetime.datetime.strptime(str(delta),'%H:%M:%S').time()