In Python, how can I put a thread to sleep until a specific time?

Solution 1:

Here's a half-ass solution that doesn't account for clock jitter or adjustment of the clock. See comments for ways to get rid of that.

import time
import datetime

# if for some reason this script is still running
# after a year, we'll stop after 365 days
for i in xrange(0,365):
    # sleep until 2AM
    t = datetime.datetime.today()
    future = datetime.datetime(t.year,t.month,t.day,2,0)
    if t.hour >= 2:
        future += datetime.timedelta(days=1)
    time.sleep((future-t).total_seconds())
    
    # do 2AM stuff

Solution 2:

import pause
from datetime import datetime

pause.until(datetime(2015, 8, 12, 2))

Solution 3:

One possible approach is to sleep for an hour. Every hour, check if the time is in the middle of the night. If so, proceed with your operation. If not, sleep for another hour and continue.

If the user were to change their clock in the middle of the day, this approach would reflect that change. While it requires slightly more resources, it should be negligible.

Solution 4:

Another approach, using sleep, decreasing the timeout logarithmically.

def wait_until(end_datetime):
    while True:
        diff = (end_datetime - datetime.now()).total_seconds()
        if diff < 0: return       # In case end_datetime was in past to begin with
        time.sleep(diff/2)
        if diff <= 0.1: return

Building on the answer of @MZA and the comment of @Mads Y

Solution 5:

I tried the "pause" pacakage. It does not work for Python 3.x. From the pause package I extracted the code required to wait until a specific datetime and made the following def.

def wait_until(execute_it_now):
    while True:
        diff = (execute_it_now - datetime.now()).total_seconds()
        if diff <= 0:
            return
        elif diff <= 0.1:
            time.sleep(0.001)
        elif diff <= 0.5:
            time.sleep(0.01)
        elif diff <= 1.5:
            time.sleep(0.1)
        else:
            time.sleep(1)