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

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

Как отсечь время от даты в 1С

Как отсечь время от даты в 1С: НачалоДня, форматная строка, запросы и типовые ошибки. Практические примеры кода для разработчика и пользователя 1С.

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

Задача «отсечь время» возникает постоянно: при отборах в отчётах, при сравнении дат документов, при группировке данных за день в запросах, при обмене данными с внешними системами. Способов несколько — от встроенных функций языка до функций языка запросов, и у каждого свои границы применения.

Ниже разобраны основные приёмы: функция НачалоДня(), приведение через форматную строку, функции НАЧАЛОПЕРИОДА и ДАТАВРЕМЯ в запросах, а также типовые ошибки, которые приводят к «потерянным» документам в отчётах.

Почему в 1С дата всегда содержит время

Тип «Дата» во встроенном языке 1С — это единое значение «дата и время». Отдельного типа «только день» в платформе нет. Когда реквизит документа имеет состав даты «Дата», платформа просто обнуляет время при вводе, но физически хранится всё равно полное значение.

Из-за этого возникают типичные проблемы. Сравнение Документ.Дата = '20260312' не найдёт документ, проведённый в 14:35. Отбор в динамическом списке «за сегодня» без учёта времени покажет только записи с нулевым временем. Группировка в запросе по полю «Дата» разобьёт один день на множество строк — по числу различных значений времени.

Функция НачалоДня() — основной способ в коде

Самый правильный способ отсечь время во встроенном языке — функция НачалоДня(). Она принимает дату и возвращает ту же дату с временем 0:00:00:

ДатаДокумента = ДокументОбъект.Дата; // 12.03.2026 14:35:21

ДатаБезВремени = НачалоДня(ДатаДокумента); // 12.03.2026 0:00:00

Если НачалоДня(ДатаДокумента) = НачалоДня(ТекущаяДатаСеанса()) Тогда

// документ от сегодняшнего дня

КонецЕсли;

Рядом работают родственные функции: КонецДня() возвращает 23:59:59 того же дня, НачалоМесяца(), НачалоКвартала(), НачалоГода(), НачалоНедели() — начало соответствующего периода. Пара НачалоДня/КонецДня особенно удобна для отборов за один день:

Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаОтбора));

Запрос.УстановитьПараметр("КонецПериода", КонецДня(ДатаОтбора));

Отсечение времени в запросах: НАЧАЛОПЕРИОДА

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

ВЫБРАТЬ

НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ) КАК День,

СУММА(Продажи.СуммаОборот) КАК Сумма

ИЗ

РегистрНакопления.Продажи.Обороты КАК Продажи

СГРУППИРОВАТЬ ПО

НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ)

Такая группировка собирает все движения внутри суток в одну строку независимо от времени. Это стандартный приём для отчётов «по дням». Аналогично можно группировать по НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД.

Для сравнения дат в условии ГДЕ тоже лучше использовать НАЧАЛОПЕРИОДА, а не приведение к строке: функция работает с индексами и не ломает оптимизацию запроса, в отличие от преобразований через ПОДСТРОКА.

Форматная строка: когда нужно только показать дату

Если задача — не сравнить, а вывести дату без времени пользователю, достаточно функции Формат():

СтрокаДаты = Формат(ДатаДокумента, "ДЛФ=D"); // "12.03.2026"

СтрокаДаты = Формат(ДатаДокумента, "ДФ='dd.MM.yyyy'"); // то же самое явно

Ключевое ограничение: Формат() возвращает строку, а не дату. Сравнивать такие строки как даты нельзя — строковое сравнение «31.12.2026» и «01.01.2026» даст неверный порядок, если сравнивать лексикографически в другом формате. Для логики и отборов используйте НачалоДня, а Формат оставьте для представления в сообщениях, печатных формах и наименованиях.

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

Сравнение способов

НачалоДня()

Код модулей, сравнения, параметры запросов. Возвращает дату — подходит для логики.

НАЧАЛОПЕРИОДА(..., ДЕНЬ)

Группировки и условия внутри запроса. Не работает вне языка запросов.

Формат(Дата, "ДЛФ=D")

Только вывод пользователю. Возвращает строку, не годится для сравнений.

Состав даты реквизита

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

Профилактика: состав даты у реквизитов

Часто время «появляется» потому, что у реквизита в конфигураторе состав даты установлен как «Дата и время». Если бизнес-смысл поля — только день (дата рождения, дата договора, дата поставки), правильнее исправить метаданные: в свойствах реквизита установить «Состав даты» = «Дата». Тогда платформа сама обнуляет время при записи, и отсекать его в коде не придётся.

Менять состав даты у существующего реквизита, в котором уже есть данные со временем, нужно осторожно: при реструктуризации время будет отброшено безвозвратно. Перед изменением сделайте резервную копию информационной базы и проверьте, не используется ли время этого поля в каких-либо алгоритмах.

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

Самая частая ошибка — сравнение даты документа с датой-константой без приведения: Если Док.Дата = '20260312' Тогда. Литерал имеет нулевое время, документ — реальное, равенства нет. Вторая ошибка — отбор «с 01.03 по 31.03», где конец периода задан как 31.03 0:00:00: весь день 31 марта выпадает из выборки. Правильно — использовать КонецДня() или Границу с видом «Включая».

Третья ошибка — отсечение времени через строковые преобразования в запросе (ПОДСТРОКА от представления даты). Это медленно, зависит от региональных настроек сервера и ломается при смене формата. Используйте НАЧАЛОПЕРИОДА.

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

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

Сравнение двух дат одного дня
Норма

НачалоДня(Дата1) = НачалоДня(Дата2) возвращает Истина

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

Равенство Ложь при визуально одинаковом дне — время не отсечено

Отбор за один день в запросе
Норма

В выборку попадают документы с любым временем этого дня

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

Попадают только записи с временем 0:00:00

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

Одна строка на календарный день

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

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

FAQ

Чем НачалоДня отличается от ДатаВремя с нулевым временем?

Результат одинаков — дата с временем 0:00:00. Но НачалоДня читаемее и не требует вручную собирать дату через Дата(Год, Месяц, День). В запросах аналог — НАЧАЛОПЕРИОДА, а конструктор ДАТАВРЕМЯ(Год, Месяц, День) тоже даёт нулевое время.

Как получить конец дня для отбора?

Используйте КонецДня(Дата) — возвращает 23:59:59. Либо в запросе передайте границу: Новый Граница(КонецДня(Дата), ВидГраницы.Включая). Просто НачалоДня последнего дня в качестве конца периода — ошибка: весь день выпадет из выборки.

Можно ли отсечь время в СКД без изменения запроса?

Да. В настройках СКД у поля даты можно задать формат ДЛФ=D для отображения, а для группировки по дням использовать в запросе вычисляемое поле с НАЧАЛОПЕРИОДА или встроенные периодичности при работе с виртуальными таблицами регистров.

Почему сравнение дат даёт Ложь, хотя день одинаковый?

Потому что сравниваются полные значения «дата + время». Документ в 14:35 не равен дате-константе с нулевым временем. Оберните обе стороны в НачалоДня() — тогда сравнение идёт по календарному дню.

Как отсечь время при обмене данными с внешней системой?

При выгрузке в XML/JSON дату обычно преобразуют в строку нужного формата через Формат() или ЗаписатьДатуJSON с вариантом ISO. Если внешняя система ждёт только день, формируйте строку вида «2026-03-12» явно, а не полагайтесь на сериализацию по умолчанию — она включает время.

Итог

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

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