[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_left>secs_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