Sleep till next 15 minute hourly interval (00:00, 00:15, 00:30, 00:45)

Question:

I need my script to sleep till the next 15 minute hourly interval, e.g. on the hour, quarter past, half past, and quarter too.

It will look something like this

While True:
    //do something
    sleepy_time = //calculate time to next interval
    time.sleep(sleepy_time)

You could write a series of if statements to check what the current minutes past the hour is then do ‘if current < 15’ and ‘if current < 30’ etc but that seems messy and inefficient.

EDIT: Building on @martineau’s answer this is the code I went with.

import datetime, time

shouldRun = True
if datetime.datetime.now().minute not in {0, 15, 30, 45}:
    shouldRun = False
# Synchronize with the next quarter hour.
while True:
    if shouldRun == False:
        current_time = datetime.datetime.now()
        seconds = 60 - current_time.second
        minutes = current_time.minute + 1
        snooze = ((15 - minutes%15) * 60) + seconds
        print('minutes:', minutes, 'seconds', seconds, ' sleep({}):'.format(snooze))
        localtime = time.asctime( time.localtime(time.time()))
        print("sleeping at " + localtime)
        time.sleep(snooze)  # Sleep until next quarter hour.
        shouldRun = True
    else:
        localtime = time.asctime( time.localtime(time.time()))
        print("STUFF HAPPENS AT " + localtime)
        shouldRun = False

The difference between his answer and this is that this run the else block only once per interval then if the minute is still on the 0, 15, 30, 45 interval calculates the extra seconds to add to the minutes to sleep till the next interval.

Asked By: Flatlyn

||

Answers:

You can achieve this using datetime

A call to datetime.datetime.now() will return a datetime which you can get the current minute past the hour with .minute.

Once we have the number of minutes past the hour, we can do that modulo 15 to get the number of minutes to the next interval of 15.

From here, simply do a call to time.sleep() with that number of minutes times 60 (60 seconds in a minute).

The code for this may look something like:

import datetime, time

minutesToSleep = 15 - datetime.datetime.now().minute % 15
time.sleep(minutesToSleep * 60)
print("time is currently at an interval of 15!")
Answered By: Joe Iddon
import time

L = 15*60

while True:
    #do something

    #get current timestamp as an integer and round to the
    #nearest larger or equal multiple of 15*60 seconds, i.e., 15 minutes
    d = int(time.time())

    m = d%L        
    sleepy_time = 0 if m == 0 else (L - m)

    print(sleepy_time)
    time.sleep(sleepy_time)
Answered By: ewcz

time.sleep(15*60 - time.time() % (15*60))

15*60 is a numer of seconds in every 15 mins.

time.time() % (15*60) would be the number of seconds passed in the current 15 min frame (since time 0 is 00:00 by definition). It grows from 0 at XX:00, XX:15, XX:30, XX:45, and up to 15*60-1 (actually, 15*60-0.(0)1 — depends on the precision of time measurements), and then starts to grow from 0 again.

15*60 - time.time() % (15*60) is the number of seconds left till the end of the 15-min frame. It, with a basic math, decreases from 15*60 to 0.

So, you need to sleep that many seconds.

However, keep in mind that sleep will not be very precise. It takes some time to process the internal instructions between time.time() is measured, and time.sleep() is actually called on the system level. Nano-fractions of a second, probably. But in most cases it is acceptable.

Also, keep in mind that time.sleep() does not always sleeps for how long it was asked to sleep. It can be waked up by signals sent to the process (e.g., SIGALRM, SIGUSR1, SIGUSR2, etc). So, besides sleeping, also check that the right time has been reached after time.sleep(), and sleep again if it was not.

Answered By: Sergey Vasilyev

I don’t think @Joe Iddon’s answer is quite right, although it’s close. Try this (note I commented-out lines I didn’t want running and added a for loop to test all possible values of minute):

import datetime, time

# Synchronize with the next quarter hour.
#minutes = datetime.datetime.now().minute
for minutes in range(0, 59):
    if minutes not in {0, 15, 30, 45}:
        snooze = 15 - minutes%15
        print('minutes:', minutes, ' sleep({}):'.format(snooze * 60))
        #time.sleep(snooze)  # Sleep until next quarter hour.
    else:
        print('minutes:', minutes, ' no sleep')
Answered By: martineau
import schedule
import time

# Define a function named "job" to print a message
def job():
    print("Job is running.")

# Set the interval for running the job function to 15 minutes
interval_minutes = 15

# Loop over the range of minutes with a step of interval_minutes
for minute in range(0, 60, interval_minutes):
    # Format the time string to be in the format of "MM:SS"
    time_string = f"{minute:02d}:00" if minute < 60 else "00:00"
    # Schedule the job function to run at the specified time every hour
    schedule.every().hour.at(time_string).do(job)

# Infinite loop to keep checking for any pending job
while True:
    schedule.run_pending()
    # Sleep for 1 second to avoid high CPU usage
    time.sleep(1)
Answered By: Carlos BL
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.