Разработка и Конфигурация · 12 мин
Как сравнить время в запросе 1С
Как сравнить время в запросе 1С: операторы сравнения дат, функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА, отбор по времени суток, типичные ошибки и примеры кода.
Сравнение даты и времени в запросах 1С — одна из базовых задач при построении отчётов, отборе документов за смену, расчёте просрочек и контроле регламентных операций. Язык запросов 1С поддерживает стандартные операторы сравнения (>, <, =, >=, <=, <>) для полей типа «Дата», а также набор функций для работы с периодами и составляющими даты.
Главная сложность в том, что тип «Дата» в 1С всегда содержит и дату, и время с точностью до секунды. Поэтому сравнение «документ за сегодня» через простое равенство почти никогда не сработает: значение 01.03.2026 14:23:05 не равно 01.03.2026 00:00:00. Для корректных отборов нужно либо задавать интервал, либо менять точность сравниваемого значения функциями языка запросов.
Ниже разобраны рабочие приёмы: сравнение с параметром, отбор по интервалу, сравнение только времени суток без даты, работа с границами периодов и типичные ошибки, которые приводят к пустым или неверным выборкам.
Как устроен тип «Дата» и почему равенство не работает
В 1С значение типа «Дата» — это всегда комбинация календарной даты и времени суток с точностью до секунды. Даже если в документе время не отображается, физически оно хранится. Поле «Дата» документа содержит, например, 15.06.2026 10:31:47, а не просто «15 июня».
Следствие: условие ГДЕ Документ.Дата = &Дата вернёт записи только при совпадении до секунды. Если в параметр передали дату без времени, она интерпретируется как начало дня 00:00:00, и выборка окажется пустой либо неполной. Это самая частая причина «не работающего» отбора у начинающих разработчиков.
Правильные альтернативы равенству: сравнение через интервал (МЕЖДУ или пара условий), приведение даты к началу периода функцией НАЧАЛОПЕРИОДА или сравнение отдельных компонентов через ДЕНЬ, МЕСЯЦ, ГОД, ЧАС, МИНУТА.
Сравнение даты и времени с параметром запроса
Самый простой сценарий — отобрать записи позже или раньше заданного момента. Параметр объявляется через амперсанд и передаётся из кода методом УстановитьПараметр. Операторы сравнения работают напрямую, без преобразований:
ВЫБРАТЬ
Регистрация.Ссылка КАК Документ,
Регистрация.Дата КАК ДатаДокумента
ИЗ
Документ.Регистрация КАК Регистрация
ГДЕ
Регистрация.Дата >= &МоментНачала
И Регистрация.Дата < &МоментОкончания
Обратите внимание на пару «>= начало, < конец». Такая форма исключает неоднозначность на границе интервала: запись ровно в момент окончания попадёт уже в следующий период. Это стандартный приём при разбиении данных на смены, сутки, месяцы.
Если параметр должен задаваться датой без времени, передайте его через функции НачалоДня() и КонецДня() встроенного языка либо сформируйте границы прямо в запросе через НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА.
- 1Объявите параметр в тексте запроса: ГДЕ Таблица.Дата >= &Момент
- 2В коде передайте значение: Запрос.УстановитьПараметр("Момент", ТекущаяДатаСеанса())
- 3Для интервала используйте два параметра: начало включительно, конец исключительно
- 4Выполните запрос и проверьте, что граничные записи попали в выборку ровно один раз
Отбор документов за день, месяц или произвольный период
Для отбора за конкретный день самый надёжный вариант — интервал от начала дня до начала следующего дня. Оператор МЕЖДУ в 1С включает обе границы, поэтому с ним нужна осторожность: запись на границе 23:59:59 учтётся, но при стыковке периодов возможны двойные попадания, если границы заданы как конец и начало одного момента.
ГДЕ
Продажи.Период МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ)
И КОНЕЦПЕРИОДА(&Дата, ДЕНЬ)
Функция НАЧАЛОПЕРИОДА(Дата, Период) возвращает начало указанного периода (СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД), а КОНЕЦПЕРИОДА — соответственно конец. Например, КОНЕЦПЕРИОДА(&Дата, МЕСЯЦ) даст последнюю секунду месяца.
Альтернатива без функций — сравнение приведённого значения: ГДЕ НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ). Такой вариант читается проще, но на больших таблицах может работать медленнее, потому что функция применяется к каждой строке и мешает использовать индекс по полю даты.
Как сравнить только время суток без даты
Типичная задача — отобрать операции, совершённые в рабочие часы, ночную смену или до обеда. Здесь дату нужно отбросить и сравнивать только компоненты времени. В языке запросов для этого есть функции ЧАС(Дата), МИНУТА(Дата) и СЕКУНДА(Дата), возвращающие числа.
ВЫБРАТЬ
Чек.Ссылка КАК Чек,
Чек.Дата КАК ДатаВремя
ИЗ
Документ.ЧекККМ КАК Чек
ГДЕ
Чек.Дата МЕЖДУ &НачалоПериода И &КонецПериода
И (ЧАС(Чек.Дата) >= 22
ИЛИ ЧАС(Чек.Дата) < 6)
Пример выше отбирает чеки ночной смены — с 22:00 до 06:00. Обратите внимание: интервал «через полночь» нельзя выразить одним условием «час между 22 и 6», поэтому используется логическое ИЛИ двух условий.
Если нужно сравнить время с точностью до минут, комбинируйте функции: ЧАС(Дата) 60 + МИНУТА(Дата) >= 8 60 + 30 — условие «не раньше 08:30». Перевод в минуты от полуночи делает сравнение линейным и избавляет от сложных составных условий.
// Отбор операций до 12:30 независимо от даты
Запрос.Текст =
"ВЫБРАТЬ Операции.Ссылка
|ИЗ Документ.Операция КАК Операции
|ГДЕ ЧАС(Операции.Дата) * 60 + МИНУТА(Операции.Дата) <= 750";Сравнение с текущим моментом и пустой датой
В языке запросов нет функции «текущая дата» — её нужно передавать параметром из кода. Используйте ТекущаяДатаСеанса(), а не ТекущаяДата(): дата сеанса едина для всего сеанса и согласована с сервером, что важно в клиент-серверном режиме, где часы клиента и сервера могут расходиться.
Для проверки просрочки типичное условие выглядит так: ГДЕ Задача.СрокИсполнения < &ТекущийМомент И НЕ Задача.Выполнена. Параметр &ТекущийМомент устанавливается один раз перед выполнением запроса.
Отдельный случай — проверка на незаполненную дату. Пустая дата в 1С — это 01.01.0001 00:00:00. В запросе её задают через ДАТАВРЕМЯ(1,1,1) или сравнением с параметром, содержащим пустую дату: ГДЕ Документ.ДатаОплаты = ДАТАВРЕМЯ(1,1,1). Проверка ЕСТЬ NULL для дат не подходит — NULL возникает только при соединениях, а незаполненное поле хранит именно «нулевую» дату.
Разница между двумя датами и сравнение длительностей
Иногда требуется не просто сравнить два момента, а вычислить интервал между ними: сколько часов заказ находился в работе, какова просрочка в днях. Для этого в языке запросов есть функция РАЗНОСТЬДАТ(Дата1, Дата2, Единица), возвращающая число — количество указанных единиц (СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ и др.) между двумя датами.
ВЫБРАТЬ
Заказ.Ссылка КАК Заказ,
РАЗНОСТЬДАТ(Заказ.Дата, Заказ.ДатаОтгрузки, ЧАС) КАК ЧасовВРаботе
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
РАЗНОСТЬДАТ(Заказ.Дата, Заказ.ДатаОтгрузки, ДЕНЬ) > 3
Условие в примере отбирает заказы, обработанные дольше трёх дней. Учтите: РАЗНОСТЬДАТ считает целые единицы, поэтому интервал 2 дня 23 часа в единицах ДЕНЬ даст 2. Если нужна точность — считайте в часах или минутах и делите.
Если дата отгрузки может быть не заполнена, результат функции для пустой даты будет некорректным. Добавляйте защитное условие Заказ.ДатаОтгрузки <> ДАТАВРЕМЯ(1,1,1) или подставляйте текущий момент через ВЫБОР КОГДА ... ТОГДА &ТекущийМомент ИНАЧЕ ... КОНЕЦ.
Способы сравнения дат и времени
Подходят для сравнения точных моментов и интервалов; самый быстрый вариант, использует индекс
Удобен для отбора за период; помните, что обе границы включаются в интервал
Приведение к границам дня, месяца, года; удобно, но функция на поле таблицы замедляет запрос
Сравнение времени суток без даты; для составных условий переводите время в минуты от полуночи
Вычисление длительности между двумя моментами и сравнение её с порогом
Проверка результата и контрольные точки
После написания запроса проверьте его на граничных значениях — именно там сравнение времени ломается чаще всего. Минимальный набор проверок: запись ровно в 00:00:00 первого дня периода, запись в 23:59:59 последнего дня, запись с незаполненной датой и запись ровно на границе интервала.
Удобно отладить условие в консоли запросов: выполните запрос с тестовыми параметрами и убедитесь, что граничные документы попадают в выборку ровно один раз. Если отчёт стыкует периоды (смены, сутки), суммы по соседним периодам не должны дублировать друг друга.
Как проверить корректность сравнения
Попадает в выборку
Не попадает — граница начала задана неверно
Попадает в период и не дублируется в следующем
Потеряна или учтена дважды
Записи с ДАТАВРЕМЯ(1,1,1) обрабатываются отдельным условием
Попадают в выборку как самые ранние или искажают РАЗНОСТЬДАТ
Условие по полю даты без обёртки в функции
Функция применяется к полю таблицы — запрос сканирует всё
Частые вопросы
Можно ли сравнить дату со строкой вида «01.03.2026»?
Нет, сравнивать нужно значения типа «Дата». Строку сначала преобразуйте в коде через Дата("20260301") или передайте параметр правильного типа. Сравнение даты со строкой либо даст ошибку, либо приведёт к неочевидному результату из-за неявного преобразования.
Как сравнить даты без учёта времени?
Приведите обе стороны к началу дня: НАЧАЛОПЕРИОДА(Поле, ДЕНЬ) = НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ). На больших таблицах предпочтительнее интервал Поле >= НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И Поле < ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ), ДЕНЬ, 1) — он не мешает использованию индекса.
Как отобрать записи за последние N часов?
Передайте параметр границы из кода: Запрос.УстановитьПараметр("Граница", ТекущаяДатаСеанса() - N * 3600) и условие ГДЕ Таблица.Дата >= &Граница. Либо используйте в запросе ДОБАВИТЬКДАТЕ(&ТекущийМомент, ЧАС, -&N).
Почему МЕЖДУ иногда даёт дубли при стыковке периодов?
Оператор МЕЖДУ включает обе границы. Если один период задан «с 00:00:00 по 23:59:59», а следующий «с 00:00:00 следующего дня», дублей нет, но если границы совпадают (конец одного = начало другого), запись на границе попадёт в оба. Используйте схему «начало включительно, конец исключительно».
Как сравнить время, если оно хранится в отдельном поле типа «Число» или «Строка»?
Такое встречается в старых конфигурациях. Числовое время (например, 930 для 09:30) сравнивайте арифметически. Строковое «ЧЧ:ММ» корректно сравнивается лексикографически только при формате с ведущими нулями, но надёжнее преобразовать его в число минут от полуночи ещё на этапе записи данных.
Что быстрее: МЕЖДУ или пара условий >= и < ?
С точки зрения СУБД оба варианта обычно транслируются в одинаковый план запроса, разницы в скорости практически нет. Выбирайте по смыслу: МЕЖДУ — когда обе границы включительно, пара условий — когда конец интервала исключается.
Что важно запомнить
Тип «Дата» в 1С всегда содержит время, поэтому равенство почти не используют — вместо него применяют интервалы с границей «начало включительно, конец исключительно». Для времени суток используют ЧАС, МИНУТА, СЕКУНДА, для длительностей — РАЗНОСТЬДАТ, а пустую дату проверяют через ДАТАВРЕМЯ(1,1,1). Условия по полю даты без обёртки в функции работают быстрее за счёт индекса.