Как при помощи планировщика `apscheduler` сделать паузу в выполнении программы?

Как при помощи планировщика apscheduler сделать паузу в выполнении программы, подобную time.sleep, но до точного времени?


Ответы (1 шт):

Автор решения: Стас

Можно всё же использовать time.sleep.

from datetime import datetime
import time
import re

def SleepToTime(n):
    if re.match(r"[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])\s(([0-1]\d|2[0-3])(:[0-5]\d){2}$)", n) is None:
        print("Дата или время в неправильном формате. Используйте YYYY-MM-DD HH:MM:SS. Например, 2020-06-21 20:00:05")
        return

    TimeToSleep = (datetime.strptime(n,'%Y-%m-%d %H:%M:%S') - datetime.now()).total_seconds()

    if TimeToSleep < 0:
        print("Это время прошло", int(abs(TimeToSleep)), "секунд назад")
        return 
    time.sleep(int(TimeToSleep))
    print("Задержка завершена")


SleepToTime('2020-08-09 19:25:00')

Эта функция принимает строку с датой в формате "ГГГГ-ММ-ДД ЧЧ:ММ:СС", например,

2020-06-22 10:18:00. Нужно именно в таком формате. Если вы напишете не 00, а просто 0 или не 05, а просто 5, то это не пройдёт проверку.

Передаваемая строка проверяться регулярным выражением, потом находится разница между текущим временем и передаваемым и проверяется, не прошло ли это время. Ну и выполняться задержка на указанное время. Этот способ не работает при требуемой задержке более 2 (или немного больше) месяцев. Это ограничение time.sleep в Python.

Также есть вариант без регулярных выражений:

from datetime import datetime
import time

def SleepToTime(n):
    try:
        TimeToSleep = (datetime.strptime(n,'%Y-%m-%d %H:%M:%S') - datetime.now()).total_seconds()
    except ValueError:
        print("Дата или время в неправильном формате. Используйте YYYY-MM-DD HH:MM:SS. Например, 2020-06-21 20:00:05")
        return

    if TimeToSleep < 0:
        print("Это время прошло", int(abs(TimeToSleep)), "секунд назад")
        return 
    time.sleep(int(TimeToSleep))
    print("Задержка завершена")


SleepToTime('2020-08-09 19:25:00')

В таком случае можно писать, например 2020-06-22 10:5:0, не обязательно 05 и 00.


Если вы хотите всё же использовать apScheduler, то можно использовать BlockingScheduler.

from apscheduler.schedulers.blocking import BlockingScheduler

scheduler = BlockingScheduler()

def function(text):
    print(text)
    scheduler.shutdown(wait=False)


scheduler.add_job(function, 'date', run_date=('2020-06-21 19:54:55'), args=['text'])

scheduler.start()

Эта функция вызовется всего один раз в момент наступления даты. Но scheduler всё равно продолжит блокировать процесс. Тут у вас есть 2 варианта:

  1. Писать код, который должен выполниться после задержки прямо в этой функции (вызываемой scheduler'ом).
  2. Сделать scheduler.shutdown(wait=False) и тогда блокировка завершится и код продолжит выполнение после scheduler'а.

Тут можно позволить задержку побольше. Я поставил 1000 лет и ошибок не было, возможно, он справится.

→ Ссылка