Разработка и Конфигурация · 10 мин
1С: как сравнить даты без учёта времени
Как в 1С сравнить даты без времени: НачалоДня, КонецДня, форматирование, запросы. Примеры кода, типичные ошибки и способы проверки результата.
В 1С значение типа «Дата» всегда содержит и дату, и время с точностью до секунды. Поэтому прямое сравнение Дата1 = Дата2 часто даёт ложный результат: документы за один календарный день, но введённые в 09:15 и 18:42, платформа считает разными. Для отчётов, отборов и проверок периодов нужно сравнивать именно календарные дни, отбрасывая время.
Существует несколько рабочих приёмов: приведение значений к началу дня функцией НачалоДня(), сравнение через строковое представление, использование функций языка запросов НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА, а также сравнение через разность дат. Выбор зависит от того, где выполняется сравнение — в коде модуля, в запросе, в СКД или в условном оформлении.
Ниже разобраны все основные способы с примерами кода, указаны ограничения каждого подхода и типичные ошибки, из-за которых сравнение дат «не работает».
Почему прямое сравнение дат в 1С не работает
Тип «Дата» в платформе 1С хранит момент времени: год, месяц, день, часы, минуты и секунды. Когда пользователь вводит дату документа, платформа обычно подставляет текущее время. Даже если на форме видно только «12.03.2026», внутри значение может быть «12.03.2026 14:37:02».
Следствие — условие Если Документ.Дата = '20260312' Тогда почти никогда не сработает, потому что литерал '20260312' означает полночь (00:00:00), а дата документа содержит реальное время. Это одна из самых частых причин «непонятного» поведения отборов и проверок у начинающих разработчиков.
Отдельная ловушка — пустая дата. Значение '00010101' тоже является датой с нулевым временем, и сравнение с ней по дню без предварительной проверки на заполненность может дать неожиданные результаты.
Способ 1. Сравнение через НачалоДня() в коде
Самый надёжный и читаемый приём — привести обе даты к началу дня и сравнить результаты:
Если НачалоДня(Дата1) = НачалоДня(Дата2) Тогда
// даты попадают на один календарный день
КонецЕсли;
Этот подход работает для любых операторов сравнения: равенство, «меньше», «больше», проверка вхождения в диапазон. Например, проверка, что дата отгрузки не раньше даты заказа по календарному дню:
Если НачалоДня(ДатаОтгрузки) < НачалоДня(ДатаЗаказа) Тогда
Сообщить("Отгрузка не может быть раньше дня заказа");
КонецЕсли;
Проверка попадания даты в конкретный день удобно записывается через диапазон от начала до конца дня — так не нужно вызывать функцию дважды с обеих сторон:
Если ПроверяемаяДата >= НачалоДня(ЦелевойДень)
И ПроверяемаяДата <= КонецДня(ЦелевойДень) Тогда
// дата внутри нужного дня
КонецЕсли;
Способ 2. Сравнение дат в запросе
В языке запросов 1С функции НачалоДня() нет — вместо неё используется НАЧАЛОПЕРИОДА(Поле, ДЕНЬ). Типичный запрос, отбирающий документы за один календарный день независимо от времени:
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ГДЕ
НАЧАЛОПЕРИОДА(РеализацияТоваровУслуг.Дата, ДЕНЬ) = &День
Параметр &День при этом должен содержать начало дня: Запрос.УстановитьПараметр("День", НачалоДня(НужнаяДата));. Альтернатива — передать одну дату и сравнивать с диапазоном:
ГДЕ
РеализацияТоваровУслуг.Дата МЕЖДУ &НачалоДня И &КонецДня
Здесь параметры задаются как НачалоДня(Период) и КонецДня(Период) на стороне кода. Важный нюанс: в условии МЕЖДУ границы включаются, поэтому документ ровно в 23:59:59 попадёт в выборку.
Сравнение в СКД и динамических списках
В схеме компоновки данных и отборах динамических списков действует тот же принцип: либо вычисляемое поле с НАЧАЛОПЕРИОДА(Дата, ДЕНЬ), либо отбор по диапазону. Если пользователь задаёт отбор «Дата равно 12.03.2026», стандартный отбор сравнит с полночью и ничего не найдёт — поэтому для пользовательских отчётов лучше выносить параметры «Начало периода» и «Конец периода» и применять стандартный период.
Запрос = Новый Запрос("ВЫБРАТЬ Т.Ссылка ИЗ Документ.РеализацияТоваровУслуг КАК Т ГДЕ Т.Дата МЕЖДУ &Начало И &Конец");
Запрос.УстановитьПараметр("Начало", НачалоДня(НужнаяДата));
Запрос.УстановитьПараметр("Конец", КонецДня(НужнаяДата));Способ 3. Сравнение через строку и через разность дат
Иногда дату удобно сравнить как строку. Функция Формат() с форматной строкой «ДЛФ=D» отбрасывает время:
Если Формат(Дата1, "ДЛФ=D") = Формат(Дата2, "ДЛФ=D") Тогда
// один календарный день
КонецЕсли;
Способ рабочий, но медленнее сравнения дат и зависит от региональных настроек: при переносе кода в базу с другой локалью формат может отличаться, хотя на равенство двух значений в одном сеансе это не влияет. Использовать строковое сравнение стоит только там, где нужен именно текст — например, при группировке в свёртке таблицы значений.
Ещё один вариант — сравнение количества дней между датами без привязки к началу суток:
РазностьДней = (НачалоДня(Дата2) - НачалоДня(Дата1)) / 86400;
Здесь 86400 — число секунд в сутках. Результат показывает разницу в календарных днях и удобен для проверок вида «между датами не более 3 дней».
Сравнение способов
Универсальный и быстрый вариант для модулей. Ограничений практически нет.
Правильный выбор для запросов и СКД. Требует аккуратности с параметрами и границами периода.
Подходит для группировок и отображения. Медленнее и зависит от форматных настроек.
Удобен для проверок интервалов в днях. Требует приведения к началу дня, иначе результат дробный.
Сравнение текущей даты с датой документа
Частая задача — проверить, что документ оформлен «сегодня». Здесь Дата) = НачалоДня(ТекущаяДата()) Тогда
// документ сегодняшний
КонецЕсли;
На сервере вместо ТекущаяДата() корректнее использовать ТекущаяДатаСеанса() — она учитывает часовой пояс сеанса, тогда как серверная дата может отличаться от пользовательской. Для баз с пользователями в разных часовых поясах это критично: «сегодня» на сервере может быть ещё «вчера» у пользователя.
Типичные ошибки и как их проверить
Первая ошибка — сравнение даты с литералом без времени: Документ.Дата = '20260312'. Литерал означает полночь, и условие сработает только для документов, проведённых ровно в 00:00:00. Правильно — НачалоДня(Документ.Дата) = '20260312'.
Вторая ошибка — использование КонецДня() в параметрах запроса с виртуальными таблицами регистров. Для остатков и оборотов период задаётся границей, и неправильная граница (включая/исключая точку) меняет результат. Проверяйте, что граница периода задана осознанно.
Третья ошибка — сравнение дат, одна из которых не заполнена. Пустая дата 01.01.0001 00:00:00 пройдёт любую проверку «меньше», что приведёт к ложным срабатываниям. Перед сравнением добавляйте ЗначениеЗаполнено(Дата).
Как проверить, что сравнение работает правильно
Быстрый способ убедиться в корректности — вывести оба сравниваемых значения с полным временем через Сообщить() или посмотреть их в отладчике в формате «Дата и время». Если время отличается, а сравнение должно трактовать даты как равные — значит, приведение к началу дня отсутствует.
Для запросов полезна проверка на контрольном примере: создайте два документа за один день с разным временем (например, 08:00 и 22:30) и убедитесь, что запрос с НАЧАЛОПЕРИОДА(Дата, ДЕНЬ) возвращает оба, а отбор по диапазону «НачалоДня–КонецДня» — тоже оба, включая документ в 23:59.
Как проверить результат
Сравнение через НачалоДня возвращает Истина
Сравнение возвращает Ложь — приведение к дню отсутствует
Выбираются все документы дня от 00:00 до 23:59
Попадает только документ в 00:00:00 или список пуст
Отдельная ветка логики через ЗначениеЗаполнено
Пустая дата участвует в сравнении наравне с заполненными
Часто задаваемые вопросы
Чем НачалоДня отличается от КонецДня?
НачалоДня возвращает ту же дату со временем 00:00:00, КонецДня — со временем 23:59:59. Вместе они задают границы календарного дня, что удобно для проверок вхождения и параметров запросов.
Можно ли сравнить даты без времени в запросе без НАЧАЛОПЕРИОДА?
Да, через условие МЕЖДУ с параметрами НачалоДня(Период) и КонецДня(Период), заданными в коде. Это часто быстрее, чем применять функцию к полю, потому что не мешает использованию индекса по дате.
Почему отбор «Дата = 12.03.2026» в динамическом списке ничего не находит?
Отбор сравнивает с полуночью 00:00:00, а документы имеют реальное время. Настройте отбор по диапазону (больше или равно началу дня и меньше или равно концу дня) либо добавьте вычисляемое поле с НАЧАЛОПЕРИОДА.
Как сравнить только месяц и год двух дат?
Приведите обе даты к началу месяца: НачалоМесяца(Дата1) = НачалоМесяца(Дата2) в коде или НАЧАЛОПЕРИОДА(Поле, МЕСЯЦ) в запросе. Тот же приём работает для квартала, недели и года.
Влияет ли часовой пояс на сравнение дат?
Да, если пользователи работают в разных поясах. Используйте ТекущаяДатаСеанса() вместо ТекущаяДата() на сервере, иначе граница «сегодня» может сместиться на сутки для части пользователей.
Что быстрее: НачалоДня или сравнение строк через Формат?
Сравнение значений типа «Дата» через НачалоДня быстрее и надёжнее: не выполняется преобразование в строку и нет зависимости от региональных настроек. Формат оправдан только там, где нужен текстовый результат.
Что важно запомнить
Дата в 1С всегда содержит время, поэтому сравнивайте календарные дни через НачалоДня() в коде и НАЧАЛОПЕРИОДА(Поле, ДЕНЬ) в запросах. Для диапазонов используйте пару НачалоДня/КонецДня, проверяйте заполненность дат и учитывайте часовой пояс сеанса.