В практике разработки на платформе 1С:Предприятие 8 часто возникает задача ограничить выполнение определенного кода или запретить редактирование документов в зависимости от времени суток. Например, предприятие может установить запрет на создание заказов после окончания рабочего дня или ограничить запуск тяжелых обработок в часы пиковой нагрузки. Рассмотрим подробнее, как правильно реализовать такие условия, разберем типичные ошибки и выберем наиболее надежные методы.
Самый простой и интуитивно понятный способ — это использование встроенной функции Час(). Она возвращает числовое значение часа из переданной даты (от 0 до 23). Проанализируем пример кода, который позволяет проверить, входит ли текущее время в интервал с 8:00 до 20:00.
ТекущееВремя = ТекущаяДата();
ТекущийЧас = Час(ТекущееВремя);
Если ТекущийЧас >= 8 И ТекущийЧас < 20 Тогда
// Код, который выполняется в рабочее время
Сообщить("Система доступна для работы");
Иначе
// Действия при попытке доступа в нерабочее время
Отказ = Истина;
Сообщить("Редактирование запрещено с 20:00 до 08:00");
КонецЕсли;
Важный нюанс: Обратите внимание, что условие ТекущийЧас < 20 означает, что код перестанет работать ровно в 20:00:00, так как в 20:00:01 функция Час() вернет 20, и условие перестанет выполняться. Если вам нужно захватить весь двадцатый час (до 20:59:59), используйте <= 20.
Если задача требует более высокой точности (например, разрешить работу с 8:30 до 18:15), использование только часов будет недостаточно. В этом случае мы разберем метод вычисления разницы в секундах между текущим моментом и началом текущего дня.
Выясним причину, почему это удобно: в 1С разность двух дат дает результат в секундах. Это позволяет нам привести любое время к единому числу. Посмотрим на алгоритм расчета:
НачалоДня().
ТекДата = ТекущаяДатаСеанса();
СекундСНачалаДня = ТекДата - НачалоДня(ТекДата);
// 8:30 = (8 * 3600) + (30 * 60) = 30600 секунд
// 18:15 = (18 * 3600) + (15 * 60) = 65700 секунд
ГраницаНачала = 30600;
ГраницаКонца = 65700;
Если СекундСНачалаДня >= ГраницаНачала И СекундСНачалаДня <= ГраницаКонца Тогда
// Условие выполняется
КонецЕсли;
Разберем ситуацию, когда пользователь находится во Владивостоке, а сервер 1С — в Москве. Если мы используем функцию ТекущаяДата(), код на сервере вернет московское время. Это приведет к тому, что запрет на редактирование сработает некорректно для удаленного пользователя.
Для решения этой проблемы крайне рекомендуется использовать функцию ТекущаяДатаСеанса(). Она учитывает смещение часового пояса, установленное для конкретного сеанса пользователя. Рассмотрим правильный подход к получению времени:
Всегда используйте ТекущаяДатаСеанса() в задачах, связанных с бизнес-логикой и интерфейсом пользователя.
Существует еще один интересный способ — сравнение только времени, игнорируя календарную дату. Для этого можно создать объект типа Дата, в котором год, месяц и день будут равны единице. Рассмотрим пример:
ТекДата = ТекущаяДатаСеанса();
// Формируем время на "пустую" дату (01.01.0001)
ВремяДляСравнения = Дата(1, 1, 1, Час(ТекДата), Минута(ТекДата), Секунда(ТекДата));
НачалоИнтервала = '00010101080000'; // 08:00:00
КонецИнтервала = '00010101200000'; // 20:00:00
Если ВремяДляСравнения >= НачалоИнтервала И ВремяДляСравнения <= КонецИнтервала Тогда
// Условие истинно
КонецЕсли;
Этот метод удобен тем, что позволяет использовать стандартные операторы сравнения >, <, МЕЖДУ и наглядно задавать границы в коде.
Проанализируем ситуацию, когда интервал проверки пересекает границу суток, например, с 22:00 вечера до 06:00 утра (ночная смена). Обычное условие с логическим "И" здесь не сработает, так как час не может быть одновременно больше 22 и меньше 6.
В таких случаях необходимо использовать логическое "ИЛИ":
ТекЧас = Час(ТекущаяДатаСеанса());
// Условие для ночного времени (22:00 - 06:00)
Если ТекЧас >= 22 ИЛИ ТекЧас < 6 Тогда
Сообщить("Внимание! Вы работаете в ночную смену.");
КонецЕсли;
Если ваша цель — запретить создание или редактирование документа вне установленного времени, код проверки необходимо размещать в модуле объекта, в обработчике события ПередЗаписью. Проанализируем пример реализации с учетом правил хорошего тона разработки:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// 1. Исключаем проверку при загрузке данных (обмены, миграция)
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// 2. Определяем временные границы (лучше хранить их в константах)
ЧасНачала = 8;
ЧасКонца = 20;
ТекЧас = Час(ТекущаяДатаСеанса());
// 3. Проверка условия
Если НЕ (ТекЧас >= ЧасНачала И ТекЧас < ЧасКонца) Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Редактирование документов в данной базе разрешено только с 8:00 до 20:00!";
Сообщение.Сообщить();
КонецЕсли;
КонецПроцедуры
Вместо жесткого прописывания цифр ("хардкода") в тексте модуля, мы рекомендуем:
ВремяНачалаРаботы и ВремяОкончанияРаботы) для хранения границ интервала. Это позволит администратору менять график без изменения конфигурации.ЧАС(Дата).Таким образом, мы рассмотрели основные способы программного контроля времени в 1С. Выбор конкретного метода зависит от требуемой точности (до часа или до секунды) и специфики ваших бизнес-процессов.