Разработка и Конфигурация · 9 мин
Как сравнить две даты в 1С
Как сравнить две даты в 1С: операторы сравнения, функции РазностьДат и ДобавитьКДате, работа с пустыми датами, сравнение без времени и типичные ошибки разработчиков.
Сравнение дат — одна из самых частых операций в коде 1С: проверка срока действия договора, отбор документов за период, контроль даты запрета редактирования. Встроенный язык платформы позволяет сравнивать даты напрямую обычными операторами, но у этой простоты есть подводные камни: составной тип значения, время внутри даты и пустые даты.
Тип «Дата» в 1С всегда содержит и календарную часть, и время с точностью до секунды. Поэтому две даты, которые «выглядят одинаково» на экране, могут оказаться неравными из-за разного времени. Ниже разобраны все рабочие способы сравнения: от простых операторов до функций работы с датами и сравнения в запросах.
Сравнение дат операторами
Значения типа «Дата» поддерживают все шесть операторов сравнения: равно (=), не равно (<>), меньше (<), больше (>), меньше или равно (<=), больше или равно (>=). Более поздняя дата считается большей. Это самый быстрый и читаемый способ, и он работает везде: в модуле объекта, в общем модуле, на клиенте и на сервере.
Если Документ.Дата > ТекущаяДатаСеанса() Тогда
Сообщить("Дата документа в будущем");
КонецЕсли;
Если СрокДействияДоговора <= ТекущаяДатаСеанса() Тогда
Сообщить("Договор истёк");
КонецЕсли;
При сравнении учитывается и время. Значение 10.03.2026 14:30:00 больше, чем 10.03.2026 00:00:00. Если логика проверки должна опираться только на календарный день, время нужно отбросить — об этом ниже.
Как сравнить даты без учёта времени
Классическая ошибка — сравнивать дату документа с датой, полученной из формы, где пользователь ввёл только день. Документ может иметь время 12:45:10, а введённое значение — 00:00:00, и проверка на равенство не сработает, хотя день один и тот же.
Чтобы сравнить только календарную часть, приведите обе даты к началу дня функцией НачалоДня():
Если НачалоДня(ДатаДокумента) = НачалоДня(ДатаОтбора) Тогда
// даты совпадают по дню
КонецЕсли;
Для проверки попадания в конкретный день удобна пара НачалоДня() и КонецДня(). КонецДня возвращает 23:59:59 указанной даты, поэтому условие Дата >= НачалоДня(Д) И Дата <= КонецДня(Д) корректно охватывает весь день целиком.
Сравнение с пустой датой
Пустая дата в 1С — это значение Дата(1,1,1), то есть 01.01.0001 00:00:00. Сравнение с ней работает обычными операторами, но нужно понимать, что пустая дата меньше любой реальной даты. Если в условии не проверить заполненность, пустое значение молча пройдёт проверку «меньше срока» и исказит логику.
Если ДатаОкончания = Дата(1,1,1) Тогда
// дата не заполнена
КонецЕсли;
// более универсальный вариант:
Если Не ЗначениеЗаполнено(ДатаОкончания) Тогда
// значение пустое (пустая дата, Неопределено, пустая ссылка)
КонецЕсли;
Функция ЗначениеЗаполнено() предпочтительнее, когда тип реквизита составной или значение может быть Неопределено — например, при обработке результата запроса с левым соединением.
Разность дат и смещение дат
Иногда нужно не просто сравнить, а узнать, сколько времени между датами. Оператор вычитания Дата1 - Дата2 возвращает разность в секундах. Для получения разности в днях, месяцах или годах используйте функцию РазностьДат(Дата1, Дата2, ТипРазности):
ДнейПросрочки = РазностьДат(СрокОплаты, ТекущаяДатаСеанса(), "ДЕНЬ");
Если ДнейПросрочки > 0 Тогда
Сообщить("Просрочка: " + ДнейПросрочки + " дн.");
КонецЕсли;
Обратная задача — получить дату, сдвинутую на заданный срок, и сравнить её с другой датой. Для этого служит ДобавитьКДате(Дата, Тип, Количество). Например, проверка, что до окончания договора осталось меньше 30 дней:
Если ДобавитьКДате(ТекущаяДатаСеанса(), "ДЕНЬ", 30) >= ДатаОкончанияДоговора Тогда
// меньше месяца до окончания
КонецЕсли;
Если НачалоДня(Дата1) = НачалоДня(Дата2) Тогда
Сообщить("Один день");
КонецЕсли;Сравнение дат в запросах
В языке запросов 1С даты сравниваются теми же операторами в секции ГДЕ, но константы даты задаются через литерал ДАТАВРЕМЯ(год, месяц, день, часы, минуты, секунды). Передавать дату параметром предпочтительнее — это защищает от ошибок форматирования и позволяет оптимизатору корректно работать с индексами.
ВЫБРАТЬ
Реализация.Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода
При использовании оператора МЕЖДУ помните: границы включаются, и если в параметр КонецПериода передана дата с временем 00:00:00, весь последний день кроме полуночи выпадет. Передавайте КонецДня() от нужной даты или используйте виртуальные таблицы с параметром «Периодичность», где платформа обрабатывает границы сама.
Для отбора по дню без учёта времени в запросе применяются функции НАЧАЛОПЕРИОДА(Дата, ДЕНЬ) и КОНЕЦПЕРИОДА(Дата, ДЕНЬ). Проверку на пустую дату в запросе выполняют сравнением с ДАТАВРЕМЯ(1,1,1).
Как выбрать способ сравнения
Текущая дата: на клиенте и на сервере
Для сравнения с «сейчас» в серверном коде используйте ТекущаяДатаСеанса() — она возвращает время сеанса с учётом часового пояса, назначенного пользователю. Функция ТекущаяДата() доступна только на клиенте и возвращает время компьютера пользователя, которое может быть неточным или намеренно изменённым.
Сравнивать бизнес-даты (сроки оплаты, даты запрета редактирования) с клиентским временем небезопасно: пользователь с правами администратора своего ПК может сдвинуть часы и обойти проверку. Всегда выполняйте такие проверки на сервере через ТекущаяДатаСеанса().
Проверка результата и отладка сравнений
Когда сравнение ведёт себя неожиданно, первым делом выведите оба значения с полным временем. Визуально одинаковые даты часто различаются секундами. Используйте Формат(Дата, "ДЛФ=DT") или просто выведите значение в сообщении — по умолчанию дата отображается с временем.
Как проверить результат
Значения совпадают по дате и времени, как ожидалось
Время различается — добавьте НачалоДня() или КонецДня()
Документы последнего дня попадают в выборку
Последний день выпадает — конец периода передан как 00:00:00
Пустое значение обрабатывается отдельной веткой
Пустая дата проходит условие сравнения — нет проверки ЗначениеЗаполнено()
Полезный приём отладки — временно заменить сложное условие на вывод промежуточных значений: результатов НачалоДня(), РазностьДат() и самих сравниваемых дат. В большинстве случаев причина видна сразу после первого вывода.
Что важно запомнить
Даты в 1С сравниваются обычными операторами, но тип «Дата» всегда содержит время. Для сравнения по дню используйте НачалоДня(), для пустых значений — Дата(1,1,1) или ЗначениеЗаполнено(), для разности — РазностьДат(), а проверки с «текущим моментом» выполняйте на сервере через ТекущаяДатаСеанса().
Частые вопросы
Как проверить, что две даты относятся к одному месяцу?
Сравните начала месяцев: НачалоМесяца(Дата1) = НачалоМесяца(Дата2). Аналогично работают НачалоГода(), НачалоКвартала() и НачалоНедели() для соответствующих периодов.
Чем отличается вычитание дат от функции РазностьДат?
Оператор вычитания возвращает разность в секундах как число. РазностьДат() возвращает разность в указанных единицах (секунды, минуты, часы, дни, месяцы, годы) и корректно обрабатывает календарные границы, например разную длину месяцев.
Почему сравнение даты со строкой не работает?
Строка «10.03.2026» и значение типа «Дата» — разные типы, их сравнение всегда даёт ложь или ошибку в зависимости от контекста. Строку нужно преобразовать: например, через Дата(год, месяц, день) с числовыми параметрами, извлечёнными из строки.
Как сравнить даты в разных часовых поясах?
Используйте универсальное время: функция ТекущаяУниверсальнаяДата() возвращает время в UTC. Храните и сравнивайте даты в едином поясе, а в пояс пользователя переводите только для отображения.
Работает ли сравнение дат в управляемых формах на клиенте?
Да, операторы сравнения и функции НачалоДня(), КонецДня(), РазностьДат() доступны и в клиентском контексте. Ограничение касается только ТекущаяДатаСеанса() — она серверная, на клиенте доступна ТекущаяДата().
Как проверить, что дата попадает в период, включая границы?
Используйте составное условие: Дата >= НачалоДня(НачалоПериода) И Дата <= КонецДня(КонецПериода). КонецДня() гарантирует, что последний день периода будет включён целиком, независимо от времени в проверяемой дате.