Простой способ это линуксовый крон, в нем с помощью достаточно простой грамматики можно задать интервалы в достаточно широких правилах. Там задается все так:
минута час день_недели день_месяца месяц команда
Каждое из чисел это или (*), или число (5) или несколько чисел (2,3,5, 7-10), либо пропуск (что_то/интервал).
Поэтому можно легко задавать события типо каждый второй вторник
* * 2/2 * * команда
или первое число мая
0 0 * 1 4 команда 2
На основании этого можно строить регулярные события. На них накладывать расписание праздников (и то не всегда, к примеру оплата домашних счетов не зависит от праздников). Как вариант - можно сдвигать событие, если оно попало на праздник.