Zanam
Zanam

Reputation: 4807

Python scheduling a job starting every weekday and running every hour

I currently have a sample code defined as:

import schedule
import time

def job(t):
    print ("I'm working...", t)
    return

schedule.every().day.at("01:00").do(job,'It is 01:00')

while True:
    schedule.run_pending()
    time.sleep(60) # wait one minute

I am looking to however run the code every hour on weekdays from 9AM to 4PM. i.e. every day Monday through Friday I want to run the code at 9AM, 10AM, ..., 3PM, 4PM.

Reading the documentation for schedule it seems that I can run the code individually Monday through Friday but not only weekday between two specified times.

Also, shouldn't the following time.sleep(60) make the code run perpetually?

Upvotes: 6

Views: 20555

Answers (5)

c0d3rman
c0d3rman

Reputation: 667

A better way:

schedule.every().monday.at("09:00").do(
   lambda: schedule.every().hour.until("16:00").do(job))

You can make 5 of these for each weekday, or you could do it in a more generic way:

days = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]

# Make a generic "weekday" option for schedule
def weekday(self, day):
    self.start_day = day
    return self.weeks
schedule.Job.weekday = weekday

# For each non-weekend day
for i in range(5):
    schedule.every().weekday(days[i]).at("09:00").do(
        lambda: schedule.every().hour.until("16:00").do(job))

You can also do it this way if you prefer:

for i in range(5):
    # When the workday starts, schedule a job to run every hour and tag it
    schedule.every().weekday(days[i]).at("09:00").do(
        lambda: schedule.every().hour.do(job).tag(days[i]))
    # When the workday ends, cancel the job using the tag
    schedule.every().weekday(days[(i+1) % len(days)]).at("16:00").do(
        lambda: schedule.clear(days[i]))

Use at your own risk, I didn't test for off-by-ones.

Upvotes: 1

JamesDK
JamesDK

Reputation: 96

schedule looks at the beginning interesting, but in the end not really helpful if you need a bit more.

try to use pycron

import pycron
import time

def job():
    timenow = time.localtime()
    print("I'm working...", str( time.strftime("%H:%M", timenow) )) 

while True:
#                     |----------------- on minute 0, so every full hour
#                     |  |--------------- on hours 9 till 16
#                     |  |   | |-------- every day in month and every month
#                     V  V   V V  v------ on weekdays Monday till Friday
    if pycron.is_now('0 9-16 * * mon-fri'):
        job()
time.sleep(60)

Upvotes: 2

gelkin
gelkin

Reputation: 51

You can use library APScheduler. For example:

from apscheduler.schedulers.blocking import BlockingScheduler

def job_function():
    print("Hello World")

sched = BlockingScheduler()

# Runs from Monday to Friday at 5:30 (am) until
sched.add_job(job_function, 'cron', day_of_week='mon-fri', hour=5, minute=30)
sched.start()

Upvotes: 1

Jan
Jan

Reputation: 227

The only way it worked for me is this:

import schedule
import datetime
import time

nowtime = str(datetime.datetime.now())

def job(t):
    print("I'm working...", str(datetime.datetime.now()), t)

for i in ["06:00", "09:00", "12:00", "15:00", "18:00"]:
    schedule.every().monday.at(i).do(job, i)
    schedule.every().tuesday.at(i).do(job, i)
    schedule.every().wednesday.at(i).do(job, i)
    schedule.every().thursday.at(i).do(job, i)
    schedule.every().friday.at(i).do(job, i)

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

Upvotes: 10

SPQR
SPQR

Reputation: 49

def weekday_job(x, t=None):
    week = datetime.today().weekday()
    if t is not None and week < 5:
        schedule.every().day.at(t).do(x)

weekday_job(main, '01:00')
weekday_job(main, '02:00')

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

Upvotes: 3

Related Questions