Разработка и Конфигурация · 10 мин
Как в запросе 1С сравнить даты
Как сравнить даты в запросе 1С: операторы сравнения, функции ДАТАВРЕМЯ, НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, РАЗНОСТЬДАТ, работа с периодами и типичные ошибки.
Сравнение дат — одна из самых частых операций в запросах 1С: отбор документов за период, проверка актуальности цен, вычисление просроченной задолженности. Язык запросов 1С поддерживает стандартные операторы сравнения для дат, а также набор встроенных функций для работы с периодами, границами интервалов и разностью дат.
Главная сложность связана с тем, что тип «Дата» в 1С всегда содержит и время. Значение «01.03.2026 00:00:00» и «01.03.2026 23:59:59» — разные значения, поэтому простое сравнение «равно дате» часто не даёт ожидаемого результата. Ниже разобраны рабочие приёмы: от простых операторов до функций НАЧАЛОПЕРИОДА и РАЗНОСТЬДАТ.
Все примеры применимы к управляемым и обычным приложениям на платформе 8.3, синтаксис проверяется в консоли запросов или в конструкторе запроса конфигуратора.
Простое сравнение дат операторами
Для полей типа «Дата» в условии ГДЕ работают все стандартные операторы сравнения. Чаще всего границы периода передаются как параметры запроса — это удобнее и безопаснее, чем подстановка значений в текст запроса.
ВЫБРАТЬ
Реализация.Ссылка,
Реализация.Дата
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата >= &НачалоПериода
И Реализация.Дата <= &КонецПериода
Перед выполнением запроса параметры устанавливаются в коде: Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачала)). Важно, чтобы тип параметра совпадал с типом поля — дата с датой. Передача строки вместо даты приведёт к ошибке или к пустому результату.
Оператор «равно» с датой используйте осторожно: он сравнивает значение с точностью до секунды. Если в документе дата «10.05.2026 14:32:17», то условие Дата = &Дата, где параметр равен «10.05.2026 00:00:00», не сработает. Для сравнения «в пределах одного дня» применяйте приёмы из следующего раздела.
Функция ДАТАВРЕМЯ и константные даты в запросе
Когда дату нужно зашить прямо в текст запроса (например, отсечь архивные данные до фиксированной точки), используется функция ДАТАВРЕМЯ. Она принимает числовые аргументы: год, месяц, день и опционально часы, минуты, секунды.
ГДЕ
Документ.Дата >= ДАТАВРЕМЯ(2026, 1, 1)
И Документ.Дата < ДАТАВРЕМЯ(2026, 1, 1)
Обратите внимание на приём «меньше первого числа следующего периода» вместо «меньше или равно концу текущего». Такое условие не зависит от времени внутри даты и корректно отбирает весь последний день периода, включая документы с любым временем.
Строковые литералы вида "20260101" в сравнении с датой не используйте: платформа не выполнит неявное преобразование, и запрос вернёт ошибку или неверный результат в зависимости от СУБД.
Сравнение дат без учёта времени: НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА
Функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА приводят дату к границе указанного периода. Это основной инструмент, когда нужно сравнивать даты «по дню», «по месяцу» или «по году», игнорируя время.
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ) КАК День,
СУММА(Продажи.СуммаОборот) КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты КАК Продажи
СГРУППИРОВАТЬ ПО
НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ)
Второй параметр задаёт периодичность: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД. Например, НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ) вернёт первое число месяца 00:00:00, а КОНЕЦПЕРИОДА(Дата, МЕСЯЦ) — последний день месяца 23:59:59.
Типовой сценарий — сравнить дату документа с текущим днём без времени: НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = НАЧАЛОПЕРИОДА(&ТекущаяДата, ДЕНЬ). Учтите, что применение функции к полю в условии отбора может отключить использование индекса по этому полю, что замедлит запрос на больших таблицах.
Проверка даты на пустое значение
Пустая дата в 1С — это значение 01.01.0001 00:00:00, а не NULL. Поэтому проверка «дата не заполнена» делается сравнением с ДАТАВРЕМЯ(1, 1, 1):
ГДЕ
Заказ.ДатаОтгрузки = ДАТАВРЕМЯ(1, 1, 1)
И наоборот, отбор только заполненных дат: Заказ.ДатаОтгрузки <> ДАТАВРЕМЯ(1,1,1) или Заказ.ДатаОтгрузки > ДАТАВРЕМЯ(1,1,1). Проверка ЕСТЬ NULL нужна только для соединений таблиц, где поле может отсутствовать из-за левого соединения, — это отдельный случай, не связанный с пустой датой.
Если поле составного типа и может содержать не дату, сравнение с ДАТАВРЕМЯ вернёт ложь для значений других типов без ошибки — это нормальное поведение платформы.
Вычисление разницы между датами: РАЗНОСТЬДАТ
Функция РАЗНОСТЬДАТ(Дата1, Дата2, Единица) возвращает число — сколько указанных единиц времени прошло между двумя датами. Единицы: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, КВАРТАЛ, ГОД.
ВЫБРАТЬ
Заказ.Ссылка,
РАЗНОСТЬДАТ(Заказ.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейПросрочено
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
РАЗНОСТЬДАТ(Заказ.ДатаОтгрузки, &ТекущаяДата, ДЕНЬ) > 3
Важная особенность: РАЗНОСТЬДАТ считает количество границ единиц между датами, а не полные интервалы. Разница между 23:00 и 01:00 следующего дня в единицах ДЕНЬ равна 1, хотя прошло два часа. Если нужна точная длительность, считайте в секундах или часах и делите.
Для добавления интервала к дате служит функция ДОБАВИТЬКДАТЕ(Дата, Единица, Количество). Например, условие «дата оплаты не позднее трёх дней после отгрузки»: Документ.ДатаОплаты <= ДОБАВИТЬКДАТЕ(Документ.ДатаОтгрузки, ДЕНЬ, 3).
Способы сравнения дат
Быстро, использует индекс. Подходит для сравнения с параметром, но чувствительно ко времени.
Удобно для сравнения по дню или месяцу и группировок. Может замедлять запрос на больших таблицах.
Для проверки длительности и просрочки. Считает границы единиц, а не полные интервалы.
Для сравнения с датой, сдвинутой на заданный интервал, например срок оплаты.
Сравнение дат в виртуальных таблицах и параметрах
В виртуальных таблицах регистров (Остатки, Обороты, СрезПоследних) период задаётся в параметрах таблицы, а не в секции ГДЕ. Это принципиально: условие в ГДЕ по полю Период виртуальной таблицы заставит платформу сначала вычислить всю таблицу, а потом отфильтровать — запрос станет в разы медленнее.
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаОстатков, ) КАК Остатки
Для СрезПоследних первый параметр — дата, на которую берутся актуальные значения. Сравнение даты записи с этой границей выполняет сама платформа, дополнительные условия по периоду в ГДЕ обычно не нужны.
Если в запросе нужно сравнить даты из двух соединённых таблиц (например, дата счёта и дата оплаты), условие сравнения размещайте либо в секции ГДЕ после соединения, либо прямо в условии соединения — оба варианта корректны, но перенос в условие соединения иногда ускоряет выполнение.
- 1Определите границы периода в коде: НачалоДня(ДатаНачала) и КонецДня(ДатаОкончания)
- 2Передайте их параметрами &Начало и &Конец через УстановитьПараметр
- 3В условии ГДЕ напишите: Дата >= &Начало И Дата <= &Конец
- 4Выполните запрос в консоли и проверьте, что попали документы первого и последнего дня
- 5Если последний день пуст — проверьте, что конец периода передан как 23:59:59, а не 00:00:00
Типичные ошибки при сравнении дат
Первая и самая частая ошибка — потеря документов последнего дня периода из-за передачи конца периода как начала дня. Вторая — сравнение даты со строкой: "Дата = ""20260101""" не работает, нужна функция ДАТАВРЕМЯ или параметр типа «Дата».
Третья группа ошибок связана с часовыми поясами. Функция ТекущаяДата() в серверном коде возвращает время сервера, а не пользователя. Если база работает в нескольких часовых поясах, сравнение «документ сегодняшний» может давать разный результат для разных пользователей — используйте ТекущаяДатаСеанса() и осознанно выбирайте подход.
Наконец, не забывайте про пустую дату 01.01.0001: если поле не заполнено, условие Дата < &КонецПериода его включит в выборку, что часто нежелательно. Добавляйте явную проверку на заполненность, когда это важно для логики отчёта.
Что важно запомнить
Сравнивайте даты операторами через параметры, границы периода задавайте через НачалоДня/КонецДня, константные даты — через ДАТАВРЕМЯ, сравнение без времени — через НАЧАЛОПЕРИОДА, интервалы — через РАЗНОСТЬДАТ и ДОБАВИТЬКДАТЕ. Пустая дата — это ДАТАВРЕМЯ(1,1,1), а не NULL.
Частые вопросы
Как сравнить только дату без времени в запросе 1С?
Оберните обе стороны сравнения в НАЧАЛОПЕРИОДА с периодичностью ДЕНЬ: НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ). Альтернатива — передать в коде границы дня и сравнить операторами Дата >= &Начало И Дата <= &Конец, что быстрее на больших таблицах.
Как задать дату прямо в тексте запроса?
Используйте функцию ДАТАВРЕМЯ(год, месяц, день, час, минута, секунда), например ДАТАВРЕМЯ(2026, 12, 31, 23, 59, 59). Время можно опустить — тогда оно будет 00:00:00.
Почему условие «Дата = &Дата» не находит документ?
Потому что дата документа содержит время, а параметр обычно передан с нулевым временем. Проверьте значение параметра и либо сравнивайте через НАЧАЛОПЕРИОДА, либо задавайте диапазон от начала до конца дня.
Как проверить, что дата не заполнена?
Сравните поле с ДАТАВРЕМЯ(1, 1, 1): условие ДатаОтгрузки = ДАТАВРЕМЯ(1,1,1) отберёт строки с пустой датой. Проверка ЕСТЬ NULL для этого не подходит — она относится к отсутствующим значениям при соединениях.
Как сравнить даты с точностью до месяца или года?
Примените НАЧАЛОПЕРИОДА с нужной периодичностью к обоим значениям: НАЧАЛОПЕРИОДА(Дата1, МЕСЯЦ) = НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ). Для разницы в месяцах или годах используйте РАЗНОСТЬДАТ(Дата1, Дата2, МЕСЯЦ) или (…, ГОД).
Что быстрее: МЕЖДУ или два условия через И?
С точки зрения результата они эквивалентны, включая границы. На практике разницы в скорости обычно нет; важнее правильно задать границы периода и не применять функции к индексированному полю в условии.