[Dave S [EMAIL PROTECTED]]
OK I may be pushing it, ;-)
Yup wink.
I need a script to sleep from any point to 8:05AM when in needs to
re-start.
So I calculate the number of seconds with the following
def secs_till_805():
# Returns the number of seconds till 8:05AM
secs_5min=5*60
secs_24hr=24*60*60
secs_8hr=(8*60*60)+secs_5min
secs_8hr_24hr=secs_24hr-secs_8hr
hours=int(strftime('%H'))
mins=int(strftime('%M'))
secs=int(strftime('%S'))
Ouch. Never try to pick apart the current time by computing it more
than once. For example, if the time at the start of that block is
just a fraction of a second before 9AM, it's quite possible you'll end
up with hours==8 and mins==secs==0 (because the time is 8:59:59 at the
time you do the %H business, and but it's 9:00:00 by the time you
get to %M). That would throw you off by an hour. The same kind of
thing can happen a little before the (any) minute changes too.
sec_left=secs_24hr-((hours*60*60)+(mins*60)+secs)
# If we are before 8:05, then ...
if sec_leftsecs_8hr_24hr:
return sec_left-secs_8hr_24hr
# If we are after 8:05, then ...
return sec_left+secs_8hr
Here's a different way, computing current time only once, and using
the datetime module to do all the fiddly work:
def seconds_until(h, m=0, s=0):
from datetime import datetime, time, timedelta
target_time = time(h, m, s)
now = datetime.now()
target = datetime.combine(now.date(), target_time)
if target now:
target += timedelta(days=1)
diff = target - now
return diff.seconds + diff.microseconds / 1e6
This returns seconds as a float, which is good (Python's time.sleep()
can make sense of floats, and sleep for fractional seconds).
Then I ...
sleep(secs_till_805())
With the above, you'd do
time.sleep(seconds_until(8, 5))
instead.
I expected the script to re-start 2-3 seconds after 8:05, python
reloading after a long sleep etc, what I get is the script restarting at
08:04.55, earlier ???
You'll probably never know why for sure. Python calls platform C
library gimmicks to sleep, which in turn invoke operating system
facilities. Understanding the whole story would require that you
understand everything all of those do.
[later]
It must be cummulative error over 10s of thousands of seconds.
Maybe.
Its a bodge ( cron or at are better) but I suppose I could calculate seconds
to 8:05 sleep(seconds*0.95), re calculate secs to 8:05 sleep(seconds)
which should reduce the error to almost zip.
That's also a good idea in order to avoid surprises due to crossing
daylight time boundaries (assuming you mean 8:05 according to the
local wall clock). Here's a function building on the above:
def sleep_until(h, m=0, s=0):
from time import sleep
while True:
delay = seconds_until(h, m, s)
if delay 10.0:
sleep(delay)
return
else:
sleep(delay / 2)
That is, it cuts the sleep time in half repeatedly, until less than 10
seconds remain. It can sleep for hours at a time, but as the target
time approaches it wakes up more frequently. This should keep the
program loaded in memory as the target time gets near.
___
Tutor maillist - [EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/tutor