I am late to the party but since this question doesn't have an answer i'll throw mine in.
I'll assume you need this for a discord py bot since this is in your tags. As @Zacky said, you should use Tasks.
A function with @tasks.loop(hours=24)
decorator won't start exactly every 24 hours, but will be scheduled in 24 hours when the function ends. This means you can delay the execution until the time you want, and then let the flow of the function continue until the end. Once there, the function will wait 24 hours to be executed again and it will correspond to the time of the day you want (plus the execution time of the function, so be careful if you want very precise function execution)
Here's how I'd do it
def seconds_until(hours, minutes):
given_time = datetime.time(hours, minutes)
now = datetime.datetime.now()
future_exec = datetime.datetime.combine(now, given_time)
if (future_exec - now).days < 0: # If we are past the execution, it will take place tomorrow
future_exec = datetime.datetime.combine(now + datetime.timedelta(days=1), given_time) # days always >= 0
return (future_exec - now).total_seconds()
@tasks.loop(hours=24)
async def job(self):
await asyncio.sleep(seconds_until(11,58)) # Will stay here until your clock says 11:58
print("See you in 24 hours from exactly now")
as @dan pointed out, this might fail if the part of the code after the wait is not instantaneous, therefore here is a better solution
def seconds_until(hours, minutes):
given_time = datetime.time(hours, minutes)
now = datetime.datetime.now()
future_exec = datetime.datetime.combine(now, given_time)
if (future_exec - now).days < 0: # If we are past the execution, it will take place tomorrow
future_exec = datetime.datetime.combine(now + datetime.timedelta(days=1), given_time) # days always >= 0
return (future_exec - now).total_seconds()
async def my_job_forever(self):
while True: # Or change to self.is_running or some variable to control the task
await asyncio.sleep(seconds_until(11,58)) # Will stay here until your clock says 11:58
print("See you in 24 hours from exactly now")
await asyncio.sleep(60) # Practical solution to ensure that the print isn't spammed as long as it is 11:58