При работе с системой 1С:Предприятие 8.3 часто возникает необходимость в автоматическом выполнении определенных операций по расписанию. Для этого мы используем регламентные задания. Однако, стандартная настройка расписания может столкнуться с трудностями, когда сервер 1С находится в часовом поясе, отличном от того, по которому мы хотим запускать задание. В частности, если нам нужно, чтобы задание всегда срабатывало, например, в 05:00 утра по Московскому времени (МСК), но сервер расположен в другом регионе, простые настройки могут привести к некорректному времени запуска.
В этой статье мы подробно разберем, как решить эту проблему, используя программный подход к управлению расписанием регламентных заданий в 1С:Предприятие. Мы выясним, почему стандартные методы могут быть неэффективны и как правильно учесть особенности часовых поясов при настройке.
Прежде чем перейти к решению, давайте проанализируем, почему возникает эта проблема. Стандартное расписание регламентного задания в 1С всегда привязано к времени сервера, на котором запущен кластер 1С:Предприятия. Это означает, что если мы укажем запуск в 05:00 в свойствах расписания, то задание будет выполняться в 05:00 по времени того часового пояса, в котором находится сервер. Если же нам нужно, чтобы задание срабатывало по Московскому времени, а сервер, допустим, находится во Владивостоке (МСК+7), то указанные 05:00 серверного времени будут совершенно другим временем по МСК.
Кроме того, платформа 1С:Предприятие внутри себя активно использует универсальное глобальное время (UTC) для синхронизации и хранения временных меток. Это еще больше усложняет прямую настройку, так как при определении времени запуска нам необходимо корректно перевести желаемое время в МСК в соответствующее время UTC, которое затем будет интерпретировано сервером 1С.
Самым надежным и гибким способом решения этой задачи является программное управление расписанием регламентного задания. Мы рассмотрим шаги, которые позволят нам точно задать время запуска по МСК, независимо от часового пояса сервера.
РасписаниеРегламентногоЗадания, используя пересчитанное время.Прежде всего, создадим само регламентное задание в конфигураторе. Нам необходимо указать его имя и метод, который будет выполняться. Расписание для него мы не указываем, так как будем управлять им программно.
Для примера, назовем наше задание "МоеЕжедневноеЗаданиеПоМСК", а выполняемый им метод будет МоиРегламентныеЗадания.ВыполнитьОперацию(). В модуле объекта общего модуля МоиРегламентныеЗадания мы можем создать метод:
// Общий модуль: МоиРегламентныеЗадания
// Должен быть помечен как 'Сервер', 'Внешнее соединение' (при необходимости)
// и 'Вызов сервера'
Процедура ВыполнитьОперацию() Экспорт
// Здесь размещается основной код, который должно выполнять регламентное задание.
// Например, загрузка данных, расчеты, формирование отчетов и т.д.
Сообщить("МоеЕжедневноеЗаданиеПоМСК выполнено в " + ТекущаяДатаСеанса());
КонецПроцедуры
Убедитесь, что для регламентного задания установлен флажок Использование, но поле Расписание оставлено пустым.
Центральной частью нашего решения будет функция, которая корректно переведет желаемое время по МСК в UTC. Платформа 1С:Предприятие 8.3 в России не учитывает летнее время, и Московское время постоянно соответствует UTC+3. Мы будем использовать это знание для простоты.
Создадим функцию для получения смещения МСК относительно UTC в секундах:
// Вспомогательная функция, можно разместить в том же общем модуле или другом подходящем
Функция ПолучитьСмещениеМСК_относительно_UTC_вСекундах() Экспорт
// Московское время (MSK) в России соответствует UTC+3.
// Летнее время в РФ отменено, поэтому смещение постоянное.
Возврат 3 * 3600; // 3 часа * 3600 секунд/час = 10800 секунд
КонецФункции
Теперь, используя эту вспомогательную функцию, мы можем создать основную функцию, которая будет принимать желаемое время по МСК (например, 05:00:00) и возвращать соответствующую ему дату и время в формате UTC:
// Вспомогательная функция для перевода времени МСК в UTC
// (для использования при установке расписания регламентного задания)
// ВремяПоМСК - это объект Дата, в котором важна только временная часть,
// например, Дата(1,1,1, 5,0,0)
Функция ПолучитьВремяПоМСКвUTC(ВремяПоМСК) Экспорт
// Определим смещение МСК относительно UTC
СмещениеМСК = ПолучитьСмещениеМСК_относительно_UTC_вСекундах();
// Для получения времени в UTC, мы вычитаем смещение МСК из желаемого времени по МСК.
// Например, если хотим 05:00 МСК, это будет 02:00 UTC (05:00 - 3 часа).
// Важно: здесь мы работаем с объектом Дата, и вычитание секунд из даты
// корректно меняет и временную, и при необходимости, дневную часть.
Возврат ВремяПоМСК - СмещениеМСК;
КонецФункции
Теперь мы можем написать процедуру, которая будет непосредственно устанавливать расписание для нашего регламентного задания. Эта процедура будет находить задание по его имени, создавать новый объект РасписаниеРегламентногоЗадания и заполнять его свойства, используя нашу функцию для пересчета времени.
// Процедура для установки расписания регламентного задания
Процедура УстановитьРасписаниеЗаданияПоМСК() Экспорт
ИмяЗадания = "МоеЕжедневноеЗаданиеПоМСК"; // Имя нашего регламентного задания
// Находим регламентное задание по имени
Задание = РегламентныеЗадания.НайтиПоИмени(ИмяЗадания);
Если Задание = Неопределено Тогда
Сообщить("Ошибка: Регламентное задание '" + ИмяЗадания + "' не найдено!");
Возврат;
КонецЕсли;
// Создаем новый объект расписания
НовоеРасписание = Новый РасписаниеРегламентногоЗадания();
НовоеРасписание.Использование = Истина; // Обязательно включаем расписание
// Указываем периодичность: ежедневно
НовоеРасписание.ПовторятьКаждые = 1; // Запускать каждый день
// Если не указаны дни недели/месяцы, то по умолчанию будет каждый день.
// Можно явно указать, если требуется более сложное расписание.
// НовоеРасписание.ДниНедели.Добавить(Неделя.Понедельник); // Пример
// ...
// Указываем диапазон действия расписания (желательно долгосрочный)
НовоеРасписание.НачалоПериода = ТекущаяДатаСеанса(); // Расписание активно с текущей даты
НовоеРасписание.КонецПериода = Дата(3000, 1, 1); // Действует до 3000 года
// **Самый важный шаг: установка времени запуска с учетом МСК.**
// Мы хотим, чтобы задание запускалось в 05:00:00 по МСК.
// Создаем дату, в которой важна только временная часть (05:00:00).
ЖелаемоеВремяПоМСК = Новый Дата(1, 1, 1, 5, 0, 0);
// Переводим желаемое время по МСК в UTC (или время, которое сервер 1С
// корректно интерпретирует с учетом своего смещения относительно UTC).
// Функция ПолучитьВремяПоМСКвUTC возвращает дату, которая соответствует
// 05:00 МСК, но выражена в UTC.
ВремяЗапускаПоСерверуВUTC = ПолучитьВремяПоМСКвUTC(ЖелаемоеВремяПоМСК);
// Устанавливаем время начала выполнения в расписании.
// Это время будет интерпретировано платформой 1С на сервере.
НовоеРасписание.ВремяНачала = ВремяЗапускаПоСерверуВUTC;
// Также можно указать Часы/Минуты, но в случае программного
// задания ВремяНачала часто более приоритетно или используется в комбинации.
// Для нашего случая, где мы точно рассчитываем DateTime,
// достаточно корректно установить ВремяНачала.
// Если же сервер находится в часовом поясе МСК, можно было бы
// НовоеРасписание.Часы.Добавить(5);
// НовоеРасписание.Минуты.Добавить(0);
// Присваиваем новое расписание регламентному заданию
Задание.Расписание = НовоеРасписание;
// Сохраняем изменения в регламентном задании.
// Без этого изменения не вступят в силу!
Задание.Сохранить();
Сообщить("Расписание для регламентного задания '" + ИмяЗадания + "' успешно установлено на 05:00 МСК.");
КонецПроцедуры
Обратите внимание на использование Новый Дата(1, 1, 1, 5, 0, 0). Мы создаем фиктивную дату, где важна только временная часть (05:00:00). Затем из этой даты мы вычитаем смещение МСК, чтобы получить соответствующее ей время в UTC. Платформа 1С корректно обрабатывает такие операции с объектами Дата.
После того как мы создали процедуру УстановитьРасписаниеЗаданияПоМСК(), нам необходимо определить, когда она будет вызываться. Есть несколько вариантов:
Если нам нужно установить расписание один раз и оно не будет меняться, мы можем вызвать эту процедуру при старте системы. Например, в обработчике события ПриНачалеРаботыСистемы общего модуля или в подписке на событие. Это гарантирует, что расписание будет установлено при первом же запуске прикладного решения.
// Пример в обработчике ПриНачалеРаботыСистемы (или в подписке)
Процедура ПриНачалеРаботыСистемы()
// ... другой код ...
Если НЕ ЗапущенаЗадачаУстановкиРасписания Тогда // Проверка, чтобы не запускать многократно
МоиРегламентныеЗадания.УстановитьРасписаниеЗаданияПоМСК();
ЗапущенаЗадачаУстановкиРасписания = Истина;
КонецЕсли;
// ...
КонецПроцедуры
Не забудьте использовать какую-либо флаг (например, константу или параметр сеанса), чтобы предотвратить многократное выполнение процедуры установки расписания при каждом запуске системы, если это не требуется.
Если существует вероятность, что расписание может быть сброшено или изменено вручную, или если мы хотим периодически проверять и корректировать расписание, мы можем создать еще одно, редко запускаемое регламентное задание (например, раз в день или раз в неделю), которое будет вызывать нашу процедуру УстановитьРасписаниеЗаданияПоМСК(). Это обеспечит постоянный контроль и восстановление расписания в случае непредвиденных изменений.
Рассмотрим несколько важных моментов и альтернатив, которые могут быть полезны:
Если сервер и Москва находятся в одном часовом поясе:
В этом случае, все гораздо проще. Можно обойтись без сложного пересчета времени и просто установить часы и минуты в расписании:
// Если сервер находится в часовом поясе МСК
НовоеРасписание.Часы.Добавить(5); // Запуск в 5 часов
НовоеРасписание.Минуты.Добавить(0); // 0 минут
Однако, так как автор темы явно указал, что сервер находится в другом часовом поясе, программный расчет, описанный выше, является предпочтительным.
Работа с ТекущаяДатаСеанса() и UTC:
Метод ТекущаяДатаСеанса() возвращает текущую дату и время серверной сессии, то есть по часовому поясу сервера. При работе с регламентными заданиями платформа 1С использует этот временной контекст и внутренние механизмы для сопоставления с UTC. Наша задача — "подготовить" время для ВремяНачала таким образом, чтобы оно, будучи интерпретированным сервером, соответствовало желаемому МСК времени.
Летнее/зимнее время в других регионах:
В Российской Федерации переход на летнее/зимнее время отменен, что упрощает расчет смещения для МСК (всегда UTC+3). Однако, если вам потребуется запускать задания по времени другого региона или страны, где действует переход на летнее время, расчет смещения может быть значительно сложнее. В таких случаях, возможно, придется использовать внешние веб-сервисы, которые предоставляют актуальную информацию о часовых поясах и их смещениях с учетом сезонных изменений.
Важность Задание.Сохранить():
Не забывайте вызывать метод Задание.Сохранить() после изменения расписания. Без этого изменения не будут применены, и регламентное задание продолжит работать по старому расписанию или не будет запускаться вовсе.
Отладка расписания:
При отладке таких заданий полезно использовать логирование. Записывайте в журнал регистрации или в текстовый файл текущее время сервера, рассчитанное время UTC и время, установленное в расписании. Это поможет проверить корректность расчетов и убедиться, что задание запускается точно в нужное время.
Мы рассмотрели все аспекты программной настройки расписания регламентных заданий в 1С:Предприятие 8.3 для корректного запуска по фиксированному часовому поясу (МСК), независимо от часового пояса сервера. Этот подход обеспечивает высокую точность и надежность, позволяя нам полностью контролировать время выполнения автоматических операций.