Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
932 views
in Technique[技术] by (71.8m points)

datetime - How to start/stop a Python function within a time period (ex. from 10 am to 12:30pm)?

I am trying to create a function (e.g. def startTime()) that executes another function like def runFunc() that starts every day on execution with python script at 10 am and stops automatically (or script ends) at 12:30 pm.

Example: startTime(start_time, stop_time,runFunc)

Can anyone help me with that?

I am trying to schedule startTime from 10 am to 12:30 pm.

import threading
import schedule
import time

def runFunc(interval, innerFunc, iterations = 0):
   if iterations != 1:
      threading.Timer (interval,runFunc, [interval, innerFunc , 0 ]).start ()
   innerFunc ()

def A():
     print "Hello World- A"
def B():
     print "Hello World- B"

I tried this but didn't work:

def startTime(job):
      schedule.every().day.at("10:00").do(job)
      while True:
           schedule.run_pending()

startTime(runFunc(60,A))
startTime(runFunc(300,B))

runFunc(60,A) runs fine, but it is unable to schedule the runFunc from 10 am to 12:30 pm.

Another way

from datetime import datetime, time
now = datetime.now()
now_time = now.time()
now_time
if time(5,27) <= now.time() <= time(5,28):
    runFunc(10,A)

runFunc does stop, but it keeps on executing after the end time.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The whole story is kind of complicated and it highly depends on what you really want to with your script. For example this code will work ok:

import threading
import schedule
import time
import datetime
import sys
def test():
    print('{} This is a test'.format(datetime.datetime.now())) #this works ok

def exit():
    print('{} Now the system will exit '.format(datetime.datetime.now())) #this works ok
    sys.exit()

schedule.every().day.at("09:57").do(test)
schedule.every().day.at('09:58').do(exit)

while True:
    schedule.run_pending()
    time.sleep(1)

You will see in your terminal the "test message" and after one minute you will see the "exit message" which actually terminates the script.

But If you apply some loops inside function test above like :

def test():
    while True: 
        print "This is a test"
        time.sleep(5)

then script will not exit. In reality function exit will not be even called since Python is trapped by the while loop inside function test and will keep going on and on.

Schedule documentation points out that scheduled jobs are called in series, so if the previous job is not finished the next job is not starting actually.

I suspect that your purpose is to have a kind of function running continuously at 10:00 and you want to force stop this function at 12:30. If it was not like this , your main function will exit as soon as he complete it's job and you wouldn't need a time frame.

In this case and in order to work around the serialize way of Python & Schedule you need to work with threads.

Combining info from Schedule Documentation on "how to execute jobs in parallel" section and info from other answers in Overflow like how to stop a running thread, this example worked fine in my pc with Python 2.7:

import threading
    import schedule
    import time
    import datetime
    import sys

def doit(stop_event, arg):
    while not stop_event.wait(1): 
        #By wait(1) you repeat the loop every 1 sec. 
        #Applying wait(0) , loops run immediatelly until to be stopped by  stop_event
        print ("working on %s" % arg)
    print("Stopping as you wish.")


def startit():
    global pill2kill
    global t
    pill2kill = threading.Event()
    t = threading.Thread(target=doit, args=(pill2kill, "task"))
    t.start()

def stopit():
    global pill2kill
    global t
    pill2kill.set()
    t.join()

#startit() #Manual call for Testing 
#time.sleep(5) #Wait 5 seconds
#stopit() #Manual call for Testing

schedule.every().day.at("12:48").do(startit)
schedule.every().day.at('12:49').do(stopit)

#schedule.every().day.at("12:50").do(startit) #Uncomment this to recall it for testing
#schedule.every().day.at('12:51').do(stopit) #Unocmment this to recall it for testing

while 1:
    schedule.run_pending()
    time.sleep(1)

You could also check out the Python Crontab library in case that suits your needs.

PS: By the way, with a quick look at source code of Python Schedule Lib it seems that the whole story is made by trapping the whole script and continuously compare date.now() with date set to run a job. This logic could be reconstructed with a couple of default commands and an infinite master loop to continiously compare dates (like Schedule Lib does).
This post has some nice snippets to make your own cron jobs, but just for testing this simplified script also works fine without external libs, calling function test when the datetime.now is within the required start/stop frame.

from datetime import datetime
import time

def test():
    global hasrun
    print('{} This is a test'.format(datetime.now()))
    time.sleep(5)
    hasrun=True

year,month,day,hour,minute=2016,12,23,15,55 
hasrun=False
now=datetime.now()

print "Now the time is :", now
jobstart=datetime(year,month,day,hour,minute)
jobstop=datetime(year,month, day,hour,minute+1)
print "Job will run at: ", jobstart
print "Job will finish at: ", jobstop
#print datetime.now() - jobstart
while True:
    while ((datetime.now() > jobstart) and (datetime.now() < jobstop )): 
        test()
    else:
        print('{} Please Wait...'.format(datetime.now()))
        if hasrun:
#           day=day+1
            minute=minute+2 #Just for Testing
            jobstart=datetime(year,month,day,hour,minute)
            jobstop=datetime(year,month, day,hour,minute+1)
            print "the job will run again ", jobstart
            print "and will finish at ", jobstop
            hasrun=False
        time.sleep(5)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...