При разработке сложных отчетов и проведении аналитики в платформе 1С:Предприятие 8.3, программисты часто сталкиваются с необходимостью сравнения дат, игнорируя временную составляющую. Тип данных «Дата» в этой системе всегда хранит информацию о годе, месяце, дне, часе, минуте и секунде. Однако для группировок, соединений таблиц или фильтрации периодов часто требуется работать исключительно с календарными сутками.
Если просто сравнить две даты, одна из которых равна 01.01.2026 00:00:00, а другая 01.01.2026 15:30:45, система посчитает их различными значениями. Это приводит к ошибкам в логике выборки и некорректным результатам отчетов. Существует несколько штатных способов нормализовать дату прямо на уровне СУБД, не прибегая к обработке результатов в коде 1С.
В данной статье мы подробно разберем встроенные функции языка запросов, синтаксические конструкции и подводные камни, связанные с производительностью при отсечении времени. Понимание этих механизмов критически важно для создания быстрых и надежных конфигураций.
Встроенная функция НачалоДня в языке запросов
Самым эффективным и рекомендуемым способом получения даты без времени является использование встроенной функции НАЧАЛОДНЯ(). Данная функция принимает на вход значение типа Дата и возвращает новую дату, у которой время установлено в ноль (00:00:00). Важно понимать, что эта операция выполняется на стороне сервера баз данных, что значительно снижает нагрузку на клиентское приложение.
Синтаксис функции предельно прост и не требует дополнительных библиотек. Вы можете применять её как к полям таблиц, так и к параметрам запроса. Например, если у вас есть поле ДатаДокумента, содержащее разное время, выражение НАЧАЛОДНЯ(ДатаДокумента) вернет единое значение для всех записей, сделанных в течение одних суток.
Использование этой функции особенно актуально в операторах ГДЕ и ИМЕЕТ. Это позволяет писать чистый и понятный код, который легко поддерживать в будущем. Ниже приведен пример корректного использования в теле запроса:
ВЫБРАТЬ
Продажи.Номенклатура,
НАЧАЛОДНЯ(Продажи.Дата) КАК ДатаБезВремени
ИЗ
Документ.РеализацияТоваровУслуг КАК Продажи
ГДЕ
НАЧАЛОДНЯ(Продажи.Дата) МЕЖДУ &НачалоПериода И &КонецПериода
Однако стоит помнить, что применение функций к полям в условии ГДЕ может в некоторых случаях препятствовать использованию индексов, если база данных не оптимизирована должным образом. В современных версиях PostgreSQL и MSSQL, используемых с 1С, оптимизатор запросов обычно справляется с этим хорошо, но тестирование производительности на больших объемах данных обязательно.
Функция НАЧАЛОДНЯ() работает быстрее, чем ручное вычисление через разность дат или конвертацию в строку, так как использует нативные возможности СУБД.
Конвертация типов через Строка и Дата
В ситуациях, когда по каким-то причинам использование НАЧАЛОДНЯ невозможно или требуется специфический формат, разработчики иногда прибегают к цепочке преобразований типов. Этот метод основан на приведении даты к строковому виду с указанием только части, отвечающей за календарь, и обратном приведении к типу Дата.
Логика метода заключается в следующем: сначала дата преобразуется в строку формата ДФ="ДД.ММ.ГГГГ". Поскольку время в этот формат не включается, оно отбрасывается. Затем полученная строка снова конвертируется в дату. При обратном преобразовании система автоматически подставляет время 00:00:00.
Несмотря на работоспособность, данный подход считается менее производительным. Операции конвертации типов требуют дополнительных вычислительных ресурсов процессора. Кроме того, такой код сложнее читать и отлаживать. Используйте этот метод только в случаях, когда стандартные функции недоступны или работают некорректно в специфических окружениях.
Пример реализации через конвертацию выглядит следующим образом:
ВЫБРАТЬ
Дата(Строка(Таблица.Дата, "ДФ=ДД.ММ.ГГГГ")) КАК ОчищеннаяДата
ИЗ
РегистрНакопления.Продажи КАК Таблица
⚠️ Внимание: При использовании конвертации через строку учитывайте настройки локали пользователя. Если формат даты в системе отличается от ожидаемого в функции
Строка, может возникнуть ошибка выполнения или некорректный результат.
Использование временных таблиц для оптимизации
При работе с большими выборками, где очистку времени от даты необходимо произвести для миллионов записей, прямое вычисление функции в основном запросе может стать «узким горлышком». В таких случаях экспертным решением является использование временных таблиц. Этот подход позволяет вынести тяжелые вычисления в отдельный этап выполнения.
Суть метода заключается в том, что сначала данные помещаются во временную таблицу, где сразу же производится нормализация дат. В дальнейшем основной запрос работает уже с подготовленными данными, где поле содержит только дату. Это не только ускоряет выборку, но и позволяет создать индексы по очищенному полю внутри временной таблицы.
Алгоритм действий выглядит так: создается временная таблица с нужной структурой, в нее помещаются данные с применением НАЧАЛОДНЯ, и далее эта таблица используется как источник для финального отчета. Такой подход особенно полезен в сложных отчетов с множеством соединений (ЛЕВОЕ СОЕДИНЕНИЕ).
☑️ Оптимизация через временные таблицы
Преимуществом данного метода является возможность многократного использования очищенной даты в разных частях отчета без повторных вычислений. Кроме того, это упрощает отладку: вы можете посмотреть содержимое временной таблицы и убедиться, что время действительно обнулено.
Сравнение производительности методов очистки
Выбор способа удаления времени из даты напрямую влияет на скорость работы вашей конфигурации. Чтобы принять взвешенное решение, необходимо понимать, как различные методы ведут себя под нагрузкой. Ниже приведена сравнительная таблица, демонстрирующая особенности подходов.
| Метод | Скорость выполнения | Читаемость кода | Нагрузка на СУБД |
|---|---|---|---|
| Функция НАЧАЛОДНЯ() | Высокая | Отличная | Минимальная |
| Конвертация Строка->Дата | Средняя | Низкая | Средняя |
| Вычисление в коде 1С | Низкая | Средняя | Высокая (сеть) |
| Временная таблица | Высокая (на больших данных) | Средняя | Средняя |
Как видно из таблицы, нативная функция запроса выигрывает по большинству параметров. Вынос вычислений в код 1С (когда мы выбираем все данные, а потом в цикле обрабатываем их) является самым непроизводительным вариантом, так как требует передачи больших объемов данных по сети между сервером и клиентом.
Использование временных таблиц оправдано только при объемах данных, превышающих сотни тысяч записей, где выигрыш от индексации перекрывает затраты на создание дополнительной структуры. В типовых задачах достаточно ограничиться функцией НАЧАЛОДНЯ.
Почему конвертация медленнее?
Операция преобразования даты в строку требует форматирования согласно локали, что является дорогостоящей операцией для процессора по сравнению с побитовой операцией обнуления времени.
Особенности работы с параметрами запроса
Частая ошибка новичков заключается в неправильной передаче параметров в запрос. Если вы передаете в параметр &Период дату с временем, а в условии используете очищение, убедитесь, что логика сравнения не нарушена. Иногда требуется очистить время не только в поле таблицы, но и в самом параметре.
Например, если пользователь выбрал в интерфейсе дату 31.01.2026 12:00, а вы хотите получить все документы за этот день, условие ГДЕ Дата < &Период может отсечь документы, созданные после 12:00. Правильным решением будет обернуть параметр в функцию: ГДЕ НАЧАЛОДНЯ(Дата) = НАЧАЛОДНЯ(&Период).
Также стоит учитывать поведение поля ввода даты в формах 1С. По умолчанию оно может подставлять текущее время. Чтобы избежать путаницы, рекомендуется явно устанавливать время в ноль при записи значения в переменную перед передачей в запрос, используя метод НачалоДня() уже на языке 1С.
Пример безопасной передачи параметра:
Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ВыбраннаяДата));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(ВыбраннаяДата));
⚠️ Внимание: Функция
КонецДня()устанавливает время23:59:59. Будьте осторожны при использовании строгих неравенств, так как документы, созданные в последнюю секунду дня, могут быть учтены или не учтены в зависимости от точности сравнения.
Типичные ошибки и способы их устранения
Несмотря на кажущуюся простоту задачи, разработчики допускают ряд системных ошибок, которые приводят к логическим сбоям в работе программ. Одной из самых распространенных является попытка сравнения даты без времени с датой, содержащей время, без предварительной нормализации обеих сторон уравнения.
Другая частая проблема возникает при группировке данных. Если вы группируете по полю Дата, а в выборке используете НАЧАЛОДНЯ(Дата), убедитесь, что поле в секции СГРУППИРОВАТЬ ПО соответствует выражению в секции ВЫБРАТЬ. В противном случае запрос может не выполниться или сгруппировать данные неверно.
Также стоит упомянуть о проблеме «плавающего» времени при импорте данных из внешних источников. Если вы загружаете данные из CSV или Excel, время может быть случайным. В таких случаях очистку времени лучше производить на этапе записи данных в регистры или документы, а не во время формирования отчета.
- 🔍 Всегда проверяйте тип возвращаемого значения: функция должна возвращать именно Дата, а не Строка.
- 📉 Избегайте вложенных функций в условиях отбора, если объем данных превышает 100 000 записей.
- 🛡️ Тестируйте запросы на репрезентативной выборке данных, а не на пустой базе.
Правильная работа с датами — фундамент стабильной системы. Игнорирование временной составляющей там, где она не нужна, упрощает логику программы и снижает вероятность появления трудноуловимых багов в будущем.
Золотое правило: очищайте время от даты как можно ближе к источнику данных, предпочтительно на уровне запроса к СУБД.
Часто задаваемые вопросы (FAQ)
Можно ли использовать функцию НАЧАЛОДНЯ в СКД (Система Компоновки Данных)?
Да, в СКД можно использовать эту функцию. Для этого необходимо добавить вычисляемое поле в набор данных и в выражении указать НАЧАЛОДНЯ(ПолеДата). Это позволит группировать данные по дням в отчетах без написания кода на 1С.
Что делать, если нужно получить только год или месяц без времени?
Для получения начала периода используйте соответствующие функции: НАЧАЛОГОДА(), НАЧАЛОМЕСЯЦА() или НАЧАЛОКВАРТАЛА(). Они работают по аналогичному принципу, обнуляя младшие составляющие даты.
Влияет ли часовой пояс сервера на работу функции НАЧАЛОДНЯ?
Функция оперирует значением даты, хранящимся в базе данных. Если сервер 1С и сервер БД находятся в разных часовых поясах, могут возникнуть расхождения при интерпретации «начала дня». Рекомендуется хранить все даты в едином стандарте времени или учитывать сдвиг при настройке кластера.
Как очистить время в управляемых формах без запроса?
В коде 1С на клиенте или сервере используйте встроенную функцию НачалоДня(ЗначениеДата). Она работает аналогично функции языка запросов и возвращает дату с временем 00:00:00.