Все же вы решили пойти сложным путем?
Если так, вы можете отловить факт изменения календаря при помощи плагина. Вопрос в том, что дальше? Календарь устроен приблизительно следующим образом:
Есть календарь который связан с пользователем, назовем его Root. Его отличает поле Type = 0. Далее у него есть атрибут CalendarRules типа EntityCollection. Это единственный объект, с таким полем, который я знаю. Как нетрудно догадаться, это набор "правил" который и определяет расписание.
Вот тут начинается интересное. Root календарь у пользователя один, но так как расписание может меняться, для хранения этой информации используются дочерние календари Type = -1. Поэтому все его правила CalendarRule имеют ссылку на InnerCalendar, а уже эти InnerCalendar, как раз определяют конечное расписание: или действующее в настоящий момент, или действовавшие в прошлом. Как правило, у дочернего календаря есть как минимум 2 правила: первое - это правило для рабочих дней, второе для рабочих часов.
Правило для рабочих дней хранится в формате iCalendar в строке вида FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,FR,SA. Правило для рабочих часов определятся полями Offset, Duration, TimeCode и Subcode.
Например, вы имеете рабочий день ПН-ПТ с 9 до 18. Правило дней будет: FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR. А правило рабочих часов будет Offset=540 (60 минут * 9 часов); Duration=480 (60 минут * 8 часов); TimeCode=0 (Avalable); SubCode=1 (Schedulable). Если есть перерыв, то это будет еще одно правило, у него тоже будет сдвиг, длинна, но другие TimeCode и SubCode, и более высокий приоритет - ExtentCode.
Не знаю, поможет ли вам это... Настоятельно рекомендую рассмотреть вариант с планированием сервиса вместо раскуривания "что поменялось".