К статье
Практический материал

Разработка и Конфигурация · 9 мин

Дата как день в запросе 1С: как отбросить время и сравнивать по дню

Как привести дату к дню в запросе 1С: НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА, сравнение без времени, выборка за день, типовые ошибки и примеры кода.

В 1С тип «Дата» всегда содержит и дату, и время с точностью до секунды. Даже если пользователь ввёл только день, в реквизите хранится значение вида 15.03.2026 00:00:00. Из-за этого сравнение дат «в лоб» часто даёт неожиданный результат: документ, проведённый в 14:35, не равен дате 15.03.2026 00:00:00, хотя относится к тому же дню.

Задача «дата как день» возникает постоянно: сгруппировать продажи по дням, выбрать документы за конкретный день, сравнить дату документа с датой-константой, построить отчёт с разрезом по дням. Во всех этих случаях нужно отбросить время и работать только с календарной частью значения.

В языке запросов 1С для этого есть специальные функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА, а также приёмы сравнения через диапазон. Ниже разобраны рабочие конструкции, их ограничения и типичные ошибки, которые приводят к «пропавшим» документам в выборках.

Почему сравнение дат напрямую даёт ошибки

Главная ловушка — оператор равенства. Условие ГДЕ Документ.Дата = &Дата сработает только если время совпадает до секунды. Документы в 1С почти всегда проводятся с текущим временем, поэтому такое условие отберёт один-два документа или не отберёт ничего.

Вторая ловушка — параметр типа «Дата», переданный из кода как ТекущаяДатаСеанса(). Эта функция возвращает дату со временем, и даже конструкция >= &Дата отсечёт утренние документы текущего дня. Перед передачей в запрос дату нужно привести к началу дня функцией НачалоДня() либо обработать уже в тексте запроса.

Третий нюанс — граница конца дня. Конец дня в 1С — это 23:59:59. Если документ проведён ровно в полночь следующего дня, он попадёт уже в другой день, и это корректно с точки зрения платформы, хотя пользователю может казаться иначе.

НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА: основной инструмент

Функция НАЧАЛОПЕРИОДА(<Дата>, <Период>) возвращает начало указанного периода для переданной даты. С параметром ДЕНЬ она отбрасывает время: НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) для значения 15.03.2026 14:35:22 вернёт 15.03.2026 00:00:00.

Функция КОНЕЦПЕРИОДА(<Дата>, <Период>) работает зеркально и возвращает конец периода: для дня это 23:59:59. Пара функций позволяет задать точный диапазон одного календарного дня.

Обе функции принимают и другие периоды — НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД, — поэтому тот же приём масштабируется на группировку по неделям и месяцам без изменения логики.

bsl
ВЫБРАТЬ
	НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ) КАК День,
	СУММА(Продажи.СуммаОборот) КАК Сумма
ИЗ
	РегистрНакопления.Продажи.Обороты КАК Продажи
СГРУППИРОВАТЬ ПО
	НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ)
УПОРЯДОЧИТЬ ПО
	День

Выборка документов за конкретный день

Правильный способ выбрать все документы за один день — сравнение диапазоном, а не равенством. Условие строится от начала до конца дня, и время документа перестаёт иметь значение.

ВЫБРАТЬ

Реализация.Ссылка,

Реализация.Дата

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ГДЕ

Реализация.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ)

И КОНЕЦПЕРИОДА(&Дата, ДЕНЬ)

И Реализация.Проведен

Альтернатива — привести дату документа к началу дня и сравнить на равенство: ГДЕ НАЧАЛОПЕРИОДА(Реализация.Дата, ДЕНЬ) = НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ). Результат тот же, но такой вариант хуже для производительности: функция применяется к полю таблицы, и индекс по дате использоваться не будет.

Если параметр &Дата передаётся из кода, можно заранее вычислить границы: НачалоДня(Дата) и КонецДня(Дата) — и передать в запрос два готовых параметра. Это самый быстрый вариант, потому что условие остаётся простым сравнением по индексированному полю.

Сравнение вариантов

МЕЖДУ НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА от параметра

Универсально, функции применяются к параметру, индекс по дате работает. Подходит почти всегда.

Равенство НАЧАЛОПЕРИОДА(Поле, ДЕНЬ)

Простое условие, но функция на поле таблицы отключает индекс — на больших таблицах будет медленно.

Границы, вычисленные в коде (НачалоДня/КонецДня)

Максимальная скорость и читаемость запроса, но требует подготовки параметров перед выполнением.

Группировка и итоги по дням

Для отчётов с разрезом по дням группировку выполняют по выражению НАЧАЛОПЕРИОДА(Период, ДЕНЬ). Виртуальные таблицы оборотов и остатков регистров умеют группировать по периодичности сами — параметр «Периодичность» виртуальной таблицы с значением «День» часто решает задачу без ручной группировки.

Если нужна колонка «День» в удобном для пользователя виде, результат можно отформатировать уже в СКД или при выводе через Формат(День, "ДЛФ=D"). В самом запросе форматировать дату в строку не стоит: строковое представление ломает сортировку и сравнение.

При группировке по дням из разных часовых поясов помните: период движений хранится в том времени, в котором записан документ. Для распределённых баз день в отчёте может не совпадать с локальным днём филиала.

Сравнение дат без учёта времени в условиях

Типовая задача — проверить, что дата документа попадает в тот же день, что и другая дата (например, дата оплаты и дата отгрузки). Сравнивать нужно приведённые значения: НАЧАЛОПЕРИОДА(Дата1, ДЕНЬ) = НАЧАЛОПЕРИОДА(Дата2, ДЕНЬ).

Для условий «раньше дня» и «позже дня» используйте строгие границы: «раньше дня» — это < НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ), «позже дня» — > КОНЕЦПЕРИОДА(&Дата, ДЕНЬ). Такие условия не зависят от времени в параметре.

Как безопасно сравнить две даты по дню
  1. 1
    Определите, какое сравнение нужно: равенство дней, раньше или позже.
  2. 2
    Приведите обе даты функцией НАЧАЛОПЕРИОДА(..., ДЕНЬ) или вычислите границы в коде через НачалоДня/КонецДня.
  3. 3
    Для «раньше дня» используйте строгое сравнение с началом дня, для «позже дня» — с концом дня.
  4. 4
    Проверьте запрос на документах с ненулевым временем — утренних и вечерних.
  5. 5
    Убедитесь, что функция не применяется к индексированному полю в условии ГДЕ на больших таблицах.

Типичные ошибки и как их проверить

Самая частая ошибка — условие Дата = &Дата, где параметр передан как начало дня. Запрос выполняется без ошибок, но возвращает пустой или неполный результат. Признак проблемы: отчёт «не видит» документы, которые точно есть в базе.

Вторая ошибка — использование <= КонецДня без учёта того, что конец дня фиксирован на 23:59:59. Это безопасно внутри дня, но при переходе через полночь легко запутаться, какой документ к какому дню относится.

Третья ошибка — приведение даты к строке для сравнения (ПОДСТРОКА или форматирование). Строковые сравнения медленны, зависят от формата и ломают порядок сортировки.

Типичные ошибки
01
Сравнение через равенство без отсечения времени — выборка теряет документы с ненулевым временем.
02
Передача ТекущаяДатаСеанса() в параметр без НачалоДня — утренние документы текущего дня выпадают из выборки.
03
Применение НАЧАЛОПЕРИОДА к полю таблицы в условии ГДЕ — индекс не используется, запрос тормозит на больших объёмах.
04
Форматирование даты в строку для сравнения — ломается сортировка и сравнение периодов.
Контрольные точки

Как проверить результат

Документ с временем 14:35 попадает в выборку за его день
Норма

Документ присутствует в результате

Тревожный признак

Документ отсутствует — условие сравнивает даты со временем

Полнота выборки за день
Норма

В выборке все проведённые документы дня, включая 00:00:00 и 23:59:59

Тревожный признак

Крайние документы дня пропадают — неверно заданы границы

Скорость запроса на рабочей таблице
Норма

Условие накладывается на поле даты напрямую, функции только на параметрах

Тревожный признак

В плане запроса полное сканирование из-за функции на поле

FAQ

Чем НАЧАЛОПЕРИОДА отличается от функции ДАТАВРЕМЯ?

ДАТАВРЕМЯ конструирует конкретное значение даты из чисел (год, месяц, день, час, минута, секунда), а НАЧАЛОПЕРИОДА вычисляет начало периода от уже существующей даты. Для отсечения времени у поля таблицы используется именно НАЧАЛОПЕРИОДА; ДАТАВРЕМЯ нужна, когда границу периода надо задать литералом прямо в тексте запроса.

Можно ли в запросе получить только дату без времени как отдельный тип?

Нет, в 1С нет отдельного типа «дата без времени» — тип «Дата» всегда включает время. «Дата как день» — это соглашение: значение приводят к 00:00:00 через НАЧАЛОПЕРИОДА или НачалоДня и дальше работают с ним как с представителем всего дня.

Как выбрать документы за вчерашний день?

Передайте в параметр вчерашнюю дату, вычисленную в коде: НачалоДня(ТекущаяДатаСеанса() - 86400), где 86400 — число секунд в сутках. Дальше применяйте стандартное условие МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И КОНЕЦПЕРИОДА(&Дата, ДЕНЬ).

Почему в СКД группировка по дням выглядит иначе, чем в ручном запросе?

В СКД для поля-периода можно задать периодичность через выражение поля или ресурс «ПериодДень» у виртуальных таблиц. Механизм тот же — приведение к началу дня, — но платформа добавляет служебные поля периодов автоматически, поэтому в тексте запроса СКД явная функция НАЧАЛОПЕРИОДА часто не нужна.

Влияет ли часовой пояс на определение дня в запросе?

Запрос работает со значениями, как они хранятся в базе, без пересчёта часовых поясов. Если документы вводятся в разных поясах, один календарный день в отчёте может не совпадать с локальным днём пользователя — это нужно учитывать при проектировании отчётов для распределённых компаний.

Что быстрее: МЕЖДУ или два условия >= и <=?

Для оптимизатора эти формы эквивалентны, разницы в производительности нет. Выбирайте по читаемости: МЕЖДУ компактнее, а пара условий нагляднее показывает, какие границы включены в диапазон.

Итог

Что важно запомнить

Дата в 1С всегда содержит время, поэтому работа «по дню» строится через приведение к границам дня: НАЧАЛОПЕРИОДА(..., ДЕНЬ) и КОНЕЦПЕРИОДА(..., ДЕНЬ) в запросе либо НачалоДня/КонецДня в коде. Сравнивайте диапазоном, не применяйте функции к индексированным полям в условиях и проверяйте выборки на документах с ненулевым временем.