Trying to find the difference between 2 datetime objects and getting only Hours, Minutes, and Seconds


I am pulling an ending time from a json api response. Then I am trying to calculate the time remaining, before the end time, to call a function after it ends.

end_time_string = data['endTime']  # Get the end time in a string in weird format
date_format = "%Y%m%dT%H%M%S.%fZ"  # Specify the date format for the datetime parser

end_time = datetime.strptime(end_time_string, date_format)  # turn the date time string into datetime object
current_time = datetime.utcnow()  # Get current time in UTC time zone, which is what CoC uses.
time_remaining = end_time - current_time  # Get the time remaining till end of war

My end_time is a datetime object. My current_time is a datetime object. But time_remaining is a timedelta object. I am able to pull the hours, minutes and seconds from the object using:

hours, minutes, seconds = map(float, str(time_remaining).split(':'))

But the problem is that sometimes the time_remaining has days in it, and sometimes it doesn’t.

1 day, 4:55:22.761359
-1 days, 23:59:08.45766

When there are days involved, specifically when the timedelta object goes negative, my script fails.

What is the best find the amount of time between my two datetime objects in ONLY hours, minutes, and seconds, without days included?

Asked By: Lzypenguin



So, a timedelta object has days, seconds and microseconds. Multiply the days by 24 to convert it into hours, and then some nice math with modulo (%) and the usefull // operator, for which I will quote something:

//: Divides the number on its left by the number on its right, rounds
down the answer, and returns a whole number.

combining everything you get a nice f-string with padding for the zeros:

f"{td.seconds//3600 + td.days*24:02}:{(td.seconds//60)%60:02}:{td.seconds%60:02}:{td.microseconds:06}"

To put this into code:

from datetime import datetime, timedelta
# 3670 seconds is 1h1m10s
tomorrow = datetime.utcnow() + timedelta(1, 3670, 123)

current_time = datetime.utcnow()

td = tomorrow - current_time
print(f"{td.seconds//3600 + td.days*24:02}:{(td.seconds//60)%60:02}:{td.seconds%60:02}:{td.microseconds:06}")

Which generates the following output:

1 day, 1:01:10.000123
Answered By: Edo Akse

timedelta is an object. One of its methods is total_seconds() so dividing by 3600 gives hours. Also dividing by another timedelta gives a float result of the ratio, so divide by timedelta(hours=1) to get the time in hours:

>>> import datetime as dt
>>> x = dt.timedelta(days=1, seconds=5000)
>>> x.total_seconds() / 3600
>>> x / dt.timedelta(hours=1)

or in hours, minutes, seconds:

>>> hours, remaining_seconds = divmod(x.total_seconds(), 3600)
>>> minutes, seconds = divmod(remaining_seconds, 60)
>>> hours, minutes, seconds
(25.0, 23.0, 20.0)
Answered By: Mark Tolonen
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.