schedule icon indicating copy to clipboard operation
schedule copied to clipboard

Scheduling jobs using crontab syntax

Open yuanshi1602 opened this issue 6 years ago • 6 comments

0,15,30,45 * * * *, how to do it

yuanshi1602 avatar Jan 30 '19 07:01 yuanshi1602

import schedule
import time

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

schedule.every(15).minutes.do(job)

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

connorskees avatar Jan 31 '19 15:01 connorskees

crontab 0,15,30,45 * * * * isn't fully supported by this library out of the box. Jobs get scheduled relative to the scheduler process start time . (applies for minutes and hours job units) That means your job will run every 15 minutes, but with some offset to the actual time. To run your jobs at exact 0, 15, 30 and 45 minutes of each hour you have to schedule jobs using days unit.

from itertools import product
step = 15  # every x minutes
for hour, minute in product(range(0, 24), range(0, 60, step)):
    time = "{hour:02d}:{minute:02d}".format(hour=hour, minute=minute)
    schedule.every().day.at(time).do(job)

or you have to start scheduler process exactly at full hour so the jobs offset to the actual time is zero.

mojeto avatar Jan 31 '19 23:01 mojeto

Simplified solution based on https://github.com/dbader/schedule/issues/248#issuecomment-432537674 is to use hour unit with minute offset

step = 15  # every x minutes
for minute in range(0, 60, step):
    time = ":{minute:02d}".format(minute=minute)
    schedule.every().hour.at(time).do(job)

mojeto avatar Jan 31 '19 23:01 mojeto

import schedule
import time

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

schedule.every(15).minutes.do(job)

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

In order to make it run in exact times, you can have it waiting until some of your minutes like 15,30,45,0 and execute the quoted script at that time

dkgitdev avatar Jun 08 '19 08:06 dkgitdev

I would really like to upvote this as a feature request

I have a task that I want to run every day at 2AM and 2PM, which in crontab would be 0 2,14 * * * (which is not readable, not python, and all the other reasons I like schedule over cron)

In schedule this does what I want:

for t in ["02:00", "14:00"]:
    schedule.every().day.at(t).do(task)

but it doesn't look the way I want. If I now go to introspect schedule.jobs it looks like I have two jobs, when really I just want to see one. For most applications I would be interested in the kinds of job I'm running (i.e. the names of each callable, or whatever), so I don't want to see it repeated unnecessarily. The whole point of the module is to make automated tasks human-readable. I would argue that this:

[
    Every 1 day at 02:00:00 do task(),
    Every 1 day at 14:00:00 do task(),
]

is less human-readable than something like this:

[
    Every 1 day at 02:00:00 and 14:00:00 do task()
]

edatpb avatar Jan 07 '20 15:01 edatpb

I also upvote for this feature.

DGMaxime avatar Mar 11 '21 12:03 DGMaxime