Вычислить время следующего выполнения Cron в C#

#c# #algorithm #crontab

#c# #алгоритм #cron

Вопрос:

У меня есть планировщик, подобный crontab. Определение времени «ММ ЧЧ, ЧД, МД»:

ММ — минуты
ЧЧ- часы
WD- дни недели
MD — дни месяца
M — месяцы

WD, MD и M допускают несколько записей, и каждый из параметров может быть нулевым, например:

 ^ ^  0, 1  ^ ^      means exucution every minute, every hour, at sunday and mondey, every day<br>

35 15 ^ ^ ^    execution every day at 15.35<br>
  

Проблема в том, как вычислить время следующего выполнения, если известна дата последнего выполнения. Я знаю, как это сделать с помощью цикла (просто добавьте 1 минуту, пока она не будет соответствовать условию), но должен быть способ получше.

Комментарии:

1. Я надеюсь, вы не недооцениваете работу. Если вы действительно хотите быть совместимым с (POSIX) cron, вам придется обслуживать гораздо больше, чем это (я знаю, я однажды реализовал это на C )

2. @kol: Я думаю, ему нужно время <strike> Noda</strike> редактировать много времени …. 🙂

3. Если это MM HH первое, то не будет ли 15 35 возникать исключение?

4. if you know last execution date — эмм … последнее выполнение не имеет ничего общего со спецификациями crontab (они являются абсолютными ссылками на время)

Ответ №1:

Я успешно использовал NCrontab именно для этой цели.

используя что-то вроде

 var schedule = CrontabSchedule.Parse("15 35 * * *");
return schedule.GetNextOccurrence(DateTime.Now);
  

Комментарии:

1. Круто! Но один вопрос. Если, например, someDate — это время выполнения, GetNextOccurence(someDate) вернет someDate?

2. Почти уверен, что он вернет следующее событие, но GetNextOccurrences(startTime, EndTime) вернет IEnumerable<DateTime> всех событий в этом диапазоне. 🙂

Ответ №2:

Cronos — еще один отличный вариант для решения этой проблемы.

Ответ №3:

Вы можете либо закодировать это самостоятельно, используя DateTime и TimeSpan — например:

 DateTime.Now == DateTime.Now.Date.AddHours (15).AddMinutes (35)
  

проверяет, является ли это 15:35 в настоящее время (и, следовательно, необходимо выполнить какое-то выполнение), аналогичные проверки могут быть реализованы для дня недели, дня месяца и т.д.

или используйте действительно хороший opensource .СЕТЕВАЯ библиотека называется NodaTime (это определенно лучший способ).

Другой вариант — использовать другую архитектуру — для приложений / служб такого типа планировщика существует открытый исходный код.СЕТЕВАЯ библиотека под названием Quartz (еще лучше), которая выполняет среди этих вычислений множество других очень полезных вещей в этом контексте.