Reputation: 2050
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.
Upvotes: 3
Views: 6226
Reputation: 20424
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!")
Upvotes: 6
Reputation: 1
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)
Upvotes: 0
Reputation: 123473
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')
Upvotes: 1
Reputation: 4189
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.
Upvotes: 4
Reputation: 13087
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)
Upvotes: 1