Как я могу выполнять код, например, простую печать («что угодно») раз в две недели в определенное время. Например, каждый второй понедельник печатайте («тест») в 13:00 по восточному поясному времени. Это должно быть без cron. Я понимаю, что существует множество решений с использованием crontab. Не вариант для меня. Другие ближайшие решения здесь основаны на библиотеке календаря и выполняют код еженедельно в определенный день, но не раз в две недели.
Кто-нибудь знает простой и легкий способ сделать это?
я пробовал это Python планирует задание, которое начинается каждый будний день и выполняется каждый час
Я ожидал, что задачи будут запускаться раз в две недели, но с этой библиотекой это невозможно.
редактировать:
в основном это, но только раз в две недели:
# Schedule Library imported
import schedule
import time
# Functions setup
def sudo_placement():
print("Do something ")
schedule.every().monday.at("09:01").do(sudo_placement)
schedule.every().monday.at("09:02").do(sudo_placement)
schedule.every().monday.at("09:03").do(sudo_placement)
while True:
schedule.run_pending()
time.sleep(1)
вроде, как бы, что-то вроде. Итак, цикл while True, который проверяет дату и время каждую минуту... если он равен понедельнику в 13:00, напечатайте ("что угодно"). затем продолжите выполнение цикла, и если он равен следующему понедельнику, выполните ту же печать («независимо»).
примерно так: geeksforgeeks.org/python-schedule-library schedule.every().monday.do(удачи) но только каждый ДРУГОЙ понедельник
больше похоже на это: schedule.every().monday.at("13:00").do(sudo_placement)
Обратите внимание, что сам cron устарел; современной альтернативой являются системные таймеры.
«Каждый второй понедельник»: с каким происхождением? Обычно говорят «каждый 1-й и 3-й понедельник месяца» или что-то, что указывает, о каком из понедельников мы говорим. Другой вариант - «каждый второй понедельник, начиная с первого понедельника января».
(Чтобы быть немного более точным в отношении того, на что я ссылался в своем предыдущем комментарии: есть много ответов, которые «без cron», но не являются родными для Python; если вы хотите не только без cron, но и в- native-Python, вы, вероятно, должны сказать это явно).
В любом случае, если вам нужно что-то более мощное, чем библиотека schedule
, которая по-прежнему является нативной для Python, рассмотрите github.com/agronholm/apscheduler. (Ответ не добавляется, потому что запросы на рекомендации библиотек не по теме, поэтому, если это правильный ответ, то этот вопрос не должен быть разрешен здесь в первую очередь).
Когда вы говорите «без cron», вы имеете в виду конкретно программу cron? Или вы имеете в виду какую-то внешнюю систему планировщика задач?
господа, я имею в виду родной питон. Я хотел бы запустить это во время цикла True на сервере Windows, чтобы в конечном итоге отправлять напоминания по электронной почте каждую неделю в понедельник в 13:00.
было бы правильно и намного проще просто запустить цикл while True, подождать 336 часов, запустить задание, повторить? Я понятия не имею, как запустить apscheduler. Я удивлен, что для этого нет лучшей библиотеки. :|
time.sleep()
не гарантируется точность, поэтому нет, это не то, на что вы можете положиться при составлении расписания.
Мы иногда используем croniter. Не совсем для вашей потребности, но больше для ограничения скорости определенных обновлений некоторого клиентского кода, указав «расписание» с использованием выражений cron.
В вашем случае вы можете сделать что-то вроде этого:
from croniter import croniter
from datetime import datetime
import pytz
def every_other(it):
while True:
t = it.get_next(datetime)
yield t
it.get_next(datetime)
# for the example
DO_SLEEP = False
max_runs = 5
# every other Monday 1pm ET, starting with the first Monday in January 2023
base = datetime(2023, 1, 1, tzinfo=pytz.timezone('EST5EDT'))
it = croniter('0 13 * * Mon', base)
for t in every_other(it):
sleep_time = t.timestamp() - time.time()
if sleep_time < 0:
continue
if max_runs <= 0:
break
max_runs -= 1
print(f'next run: {t:%Y-%m-%d %H:%M:%S %Z}')
if DO_SLEEP:
time.sleep(sleep_time)
# do whatever
Это распечатывает (работает 12 февраля 2023 г.):
next run: 2023-02-13 13:00:00 EST
next run: 2023-02-27 13:00:00 EST
next run: 2023-03-13 13:00:00 EDT
next run: 2023-03-27 13:00:00 EDT
next run: 2023-04-10 13:00:00 EDT
Скажем, мы хотели, чтобы сериал, выходящий раз в две недели, начинался 2023-02-20
вместо 2023-02-13
. Просто измените base
выше. Например:
base = datetime(2023, 2, 20, tzinfo=pytz.timezone('EST5EDT'))
Тогда даты запуска будут такими:
next run: 2023-02-20 13:00:00 EST
next run: 2023-03-06 13:00:00 EST
next run: 2023-03-20 13:00:00 EDT
next run: 2023-04-03 13:00:00 EDT
next run: 2023-04-17 13:00:00 EDT
Другими словами, просто установите base
на любой первый понедельник, который вы хотите в серии, до 13:00 по восточному времени (или любую дату и время между предыдущим понедельником после 13:00 до выбранного дня начала, до 13:00).
DO_SLEEP = True
.max_runs
, которая присутствует только в этом примере.kill -9
) и перезапустить в любое время: она возобновится с ожиданием следующего «другого понедельника» в серии (привязанного к первому понедельнику 2023 года).time.sleep()
. Возможно, стоит реализовать wait_until(timestamp)
, который ожидает все более короткие периоды времени до установленного времени. Затем это можно было бы сделать довольно точным (значительно меньше секунды).кажется, что это просто распечатывает интересующие меня даты, но это не настоящий цикл, ожидающий наступления этих дат, чтобы в конечном итоге запустить задание, когда дата и время будут выполнены.
Если вы измените DO_SLEEP=True
, то он будет ждать до следующей даты.
Я думаю, что это работает... оно выполняется при первом запуске, что не является большой проблемой. Я протестирую это больше. большое спасибо
Он не должен выполняться изначально. Если у вас есть DO_SLEEP = True
, то первое, что он сделает, это буквально заснет до первого итератора «другого понедельника», который будет позже, чем сейчас (в начале программы). Также: будьте осторожны, чтобы удалить все max_runs
, если вы хотите, чтобы это работало вечно.
Добавил несколько заметок, к вашему сведению. Насколько надежным и точным он должен быть? Планируете ли вы иметь только один график и действие?
в основном просто нужно, чтобы он отключался каждый второй понедельник в 13:00. Он запускает вызов twilio для отправки текстовых сообщений нескольким пользователям, напоминая им о том, что нужно что-то сделать. знаете ли вы, как перенести следующий запуск на следующую неделю, а не через две недели? по-прежнему хотел бы продолжить выполнение раз в две недели. Итак, на следующей неделе 2/20, затем 3/6 и т. д.
Конечно, см. обновленный ответ, раздел «Сдвиг двухнедельной последовательности».
Запланируйте задание на первый понедельник, когда вы хотите, чтобы оно выполнялось, и выполняйте это задание, как только оно выполнит необходимое расписание, на 2 недели позже ...?