Convert a Timedelta to Days, Hours and Minutes

Convert a timedelta to days, hours and minutes

If you have a datetime.timedelta value td, td.days already gives you the "days" you want. timedelta values keep fraction-of-day as seconds (not directly hours or minutes) so you'll indeed have to perform "nauseatingly simple mathematics", e.g.:

def days_hours_minutes(td):
return td.days, td.seconds//3600, (td.seconds//60)%60

How do I convert datetime.timedelta to minutes, hours in Python?

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)

How to get total hours and minutes for timedelta in Python

You can use total_seconds() to compute the number of seconds. This can then be turned into minutes or hours:

>>> datetime.timedelta(days=3).total_seconds()
259200.0

How to convert timedelta to hours

You could do as follows to convert a timedelta to the number of hours, minutes and seconds in the format you want:

def convert_to_hours(delta):
total_seconds = delta.total_seconds()
hours = str(int(total_seconds // 3600)).zfill(2)
minutes = str(int((total_seconds % 3600) // 60)).zfill(2)
seconds = str(int(total_seconds % 60)).zfill(2)
return f"{hours}:{minutes}:{seconds}"

delta = timedelta(days=3, hours=21, minutes=2, seconds=5)
# 3 days, 21:02:05

convert_to_hours(delta)
# 93:02:05

And to convert your dataframe, you can do something like this:

df["time"] = df["time"].apply(convert_to_hours)

How can I display timedelta in hours:min:sec?

By default the str() conversion of a timedelta will always include the days portion. Internally, the value is always normalised as a number of days, seconds and microseconds, there is no point in trying to 'convert' days to hours because no separate hour component is tracked.

If you want to format a timedelta() object differently, you can easily do so manually:

def format_timedelta(td):
minutes, seconds = divmod(td.seconds + td.days * 86400, 60)
hours, minutes = divmod(minutes, 60)
return '{:d}:{:02d}:{:02d}'.format(hours, minutes, seconds)

This ignores any microseconds portion, but that is trivially added:

return '{:d}:{:02d}:{:02d}.{:06d}'.format(hours, minutes, seconds, td.microseconds)

Demo:

>>> format_timedelta(timedelta(days=2, hours=10, minutes=20, seconds=3))
'58:20:03'
>>> format_timedelta(timedelta(hours=10, minutes=20, seconds=3))
'10:20:03'

convert timedelta to seconds

You should be able to use the total_seconds method. However, you'd need to access that method via the datetime accessor dt.

>>> df['duration'].dt.total_seconds()

However, if series Duration are strings/object- you should do use pd.to_timedelta

>>> pd.to_timedelta(df['duration']).dt.total_seconds()

Is there a way to format a timedelta object to be hours-minutes-seconds.MILLISECONDS?

Given your initial code example, you could use something like this:

# From your example.
c = b - a

# Get the hours, minutes, and seconds.
minutes, seconds = divmod(c.seconds, 60)
hours, minutes = divmod(minutes, 60)

# Round the microseconds to millis.
millis = round(c.microseconds/1000, 0)

print(f"Doing <something> took {hours}:{minutes:02}:{seconds:02}.{millis}")

which results in

# c = datetime.timedelta(seconds=7, microseconds=319673)
Doing <something> took 0:00:07.320

Take a look at Python’s built-in functions round() and divmod() and please poke around this and this related thread; also, please read through this and this thread to learn more about formatting timedelta objects.



Related Topics



Leave a reply



Submit