Reputation: 51
I made a countdown function (which works just fine) that returns the time remaining as a string. I'm using the strptime
and strftime
functions to sort of parse the data so I could have a variable for how many days, hours, minutes and seconds that are remaining. My code gives me an error as soon as the days exceed 31 (because of the month). Any ideas how I can fix it?
from datetime import datetime, date
a = "31 days, 23:52:51"
b = "32 days, 23:52:51"
d = datetime.strptime(b, "%d days, %H:%M:%S")
t1 = d.strftime("%d")
t2 = d.strftime("%H")
t3 = d.strftime("%M")
t4 = d.strftime("%S")
print(t1)
print(t2)
print(t3)
print(t4)
Upvotes: 2
Views: 337
Reputation: 4206
No month has 32 days, hence your error. For time differences however, just use timedelta
. You can freely add a timedelta to a datetime
object.
import re
from datetime import datetime, timedelta
now = datetime.now()
r = "^(\d+) days?, (\d+):(\d+):(\d+)$"
cases = ["1 day, 11:12:13", "31 days, 23:52:51", "32 days, 23:52:51"]
for s in cases:
m = re.match(r, s)
days, hours, minutes, seconds = [int(x) for x in m.groups()]
td = timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
print(td) # gives you the intended output (use str(td) if you want the string)
# the code below duplicates that print manually
days2 = td.days
hours2, seconds2 = divmod(td.seconds, 3600)
minutes2, seconds2 = divmod(seconds2, 60)
print(f'{days2} day{"s" if 1 < days2 else ""}, {hours2}:{minutes2:0>2}:{seconds2:0>2}')
# and finally the print of the datetime object made of current time plus our time delta
print(now+td)
Output (will change based on your clock):
1 day, 11:12:13
1 day, 11:12:13
2021-08-12 23:23:33.986973
31 days, 23:52:51
31 days, 23:52:51
2021-09-12 12:04:11.986973
32 days, 23:52:51
32 days, 23:52:51
2021-09-13 12:04:11.986973
Upvotes: 2
Reputation: 46
I think you can use timedelta class and store in it your date. Then you can extract from it days and seconds beyond the day. From this seconds you can have hour and minutes and seconds with modulo division.
from datetime import datetime, date, timedelta
a = "31 days, 23:52:51"
b = "32 days, 23:52:51"
d = timedelta(days=float(b[0:2]), hours=float(b[9:11]), minutes=float(b[12:14]),
seconds=float(b[15:]) )
print(d.days)
print(d.seconds // 3600)
print(d.seconds % 3600 //60)
print(d.seconds % 60)
Upvotes: 1
Reputation: 51
Thanks to everyone who answered I parsed the days myself in the silliest way imaginable! So I simply went like this:
index = b.find("days")
d = datetime.strptime(b[index:], "days, %H:%M:%S")
days = int(b[0:index - 1])
And in case it would be 'day' and not 'days' I added an if/else block just to make sure. Thanks everyone!
Upvotes: 0
Reputation: 23256
If x
in x days
is not a day in the month, but just a number of days, you can't pass it to strptime
and have to parse it separately.
For example, split the string on the first ,
and pass the only the second half to strptime
:
num_days, hours = b.split(',', maxsplit=1)
d = datetime.strptime(hours.strip(), "%H:%M:%S")
t1 = int(num_days.split()[0])
t2 = d.strftime("%H")
t3 = d.strftime("%M")
t4 = d.strftime("%S")
Also, in case you want to work with t2
, t3
, t4
as numbers, you should rather use
t2 = d.hour
t3 = d.minute
t4 = d.second
Upvotes: 1