В языке запросов платформы 1С:Предприятие 8.3 работа с временными интервалами является одной из самых частых задач. Разработчики постоянно сталкиваются с необходимостью отфильтровать документы по конкретному месяцу, найти записи, попадающие в диапазон времени, или просто игнорировать время суток при сравнении дат. Приведение к типу в данном контексте — это не просто смена формата отображения, а фундаментальная операция, влияющая на логику выборки и производительность системы.
Многие начинающие специалисты ошибочно полагают, что достаточно просто обрезать строковое представление даты или использовать стандартные функции языка 1С внутри текста запроса. Однако язык запросов имеет свой собственный синтаксис и набор функций, отличных от встроенного языка конфигурации. В запросах 1С 8.3 тип «Дата» всегда включает в себя и дату, и время с точностью до секунды, что часто приводит к неожиданным пропускам записей при фильтрации. Понимание механизмов усечения и конвертации критически важно для написания корректного кода.
В этой статье мы детально разберем встроенные функции обработки времени, методы приведения периодов к границам и специфические операторы сравнения. Вы узнаете, как правильно использовать функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА, а также как оптимизировать запросы, чтобы они использовали индексы базы данных, а не выполняли полный перебор таблиц.
Специфика типа Дата в языке запросов
В отличие от многих других СУБД, где дата и время могут храниться в разных полях, в 1С:Предприятие это единый тип данных. Когда вы обращаетесь к полю типа ДатаВремя в таблице базы данных, вы всегда получаете полное значение. Это создает специфическую проблему при фильтрации: если вы ищете все документы за 1 января 2026 года, простой оператор «Равно» сработает только для документов, созданных ровно в 00:00:00 этого дня.
Для решения этой проблемы используется механизм приведения к началу или концу периода. Язык запросов предоставляет мощные инструменты для манипуляции временными метками непосредственно на стороне сервера баз данных. Это позволяет избежать загрузки лишних данных в оперативную память и последующей их обработки в цикле на клиенте или сервере приложений.
Важно понимать разницу между константой даты в тексте запроса и параметром. Константа записывается в фигурных скобках, например &{20260101}, и интерпретируется движком запросов особым образом. Параметры же передаются из объекта Запрос и требуют явного указания типа или правильного форматирования в коде встроенного языка перед выполнением.
⚠️ Внимание: При передаче параметров даты из встроенного языка убедитесь, что время обнулено (установлено в 00:00:00), если вы планируете использовать их для поиска по началу дня. Иначе запись, созданная в 10:30, не попадет в выборку при условии «Равно» началу дня.
Используйте функцию ТекущаяДата() во встроенном языке только для получения текущего момента. Для формирования границ периода в запросе надежнее использовать функции НАЧАЛОДНЯ или КОНЕЦДНЯ прямо в тексте запроса.
Функции усечения и приведения периодов
Основным инструментом для работы с датами в запросах являются функции семейства НАЧАЛО.. и КОНЕЦ... Они позволяют «округлить» произвольную дату до границ стандартных временных интервалов. Это наиболее эффективный способ выразить дату в нужном формате непосредственно в условии отбора.
Рассмотрим основные функции, которые доступны в синтаксисе запроса 1С 8.3. Каждая из них принимает дату и возвращает новую дату, смещенную к границе периода. Использование этих функций гарантирует, что ваши условия выборки будут работать корректно независимо от времени, записанного в конкретном документе.
- 📅 НАЧАЛОДНЯ(Дата) — возвращает дату с обнуленным временем (00:00:00). Идеально подходит для группировки документов по суткам.
- 🗓️ НАЧАЛОМЕСЯЦА(Дата) — возвращает первое число месяца с нулевым временем. Часто используется для отчетов «Оборотно-сальдовая ведомость» или анализ продаж за месяц.
- 🏁 КОНЕЦДНЯ(Дата) — возвращает конец текущих суток (23:59:59). Полезно, когда нужно включить в выборку все события произошедшие «сегодня».
- 📆 НАЧАЛОГОДА(Дата) — возвращает 1 января указанного года. Необходимо для накопительных итогов с начала года.
Пример использования в условии отбора выглядит следующим образом: ГДЕ НАЧАЛОДНЯ(Документ.Дата) = &Период. В данном случае параметр &Период должен содержать дату без времени. Если в параметре будет время, условие может не выполниться, так как функция вернет 00:00:00, а параметр будет, например, 14:00:00.
Синтаксис констант даты и временные зоны
При написании жестких условий в тексте запроса (без параметров) используется специальный формат констант. Это упрощает чтение кода и снижает вероятность ошибок парсинга строковых представлений дат. Синтаксис требует заключения даты в фигурные скобки.
Формат записи константы: &{ГГГГММДДЧЧММСС}. Если время не указано, оно по умолчанию считается равным нулю. Например, запись &{20231231} эквивалентна 31 декабря 2023 года, 00 часов 00 минут 00 секунд. Для указания времени необходимо добавить цифры после дня: &{20231231235959}.
Особое внимание следует уделить вопросу временных зон. Платформа 1С 8.3 хранит даты в базе данных в формате UTC (всемирное координированное время). При выборке данных через запрос движок автоматически конвертирует время из UTC в локальное время пользователя или сервера, в зависимости от настроек сеанса. Однако при использовании констант в запросе система ожидает, что вы указываете время в локальном поясе, если не используется явное приведение.
| Функция / Конструкция | Описание действия | Пример результата для 15.05.2026 14:30 |
|---|---|---|
НАЧАЛОДНЯ() |
Обрезает время до начала суток | 15.05.2026 00:00:00 |
КОНЕЦМЕСЯЦА() |
Устанавливает конец текущего месяца | 31.05.2026 23:59:59 |
ДАТАВРЕМЯ() |
Конструктор даты из частей | Зависит от аргументов |
&{20260515} |
Константа даты (начало дня) | 15.05.2026 00:00:00 |
Нюансы работы с UTC
Внутреннее хранение дат в SQL-сервере всегда происходит в UTC. Если ваш сервер находится в Москве, а пользователь в Хабаровске, при выборке через запрос время будет автоматически пересчитано. Будьте осторожны при прямых SQL-запросах в обход платформы 1С — там конвертация не произойдет автоматически.
Операторы сравнения и пересечение периодов
Самая распространенная ошибка при фильтрации по датам — использование оператора «Между» (МЕЖДУ) без учета времени. Конструкция ГДЕ Дата МЕЖДУ &Начало И &Конец включает обе границы. Если в параметр &Конец передана дата начала следующего дня (например, 01.02.2026 00:00:00), то документы, созданные 1 февраля в полночь, попадут в выборку за январь, что может исказить остатки.
Правильный подход к выражению периода «с.. по..» подразумевает использование комбинации операторов «Больше или равно» и «Меньше». Для получения всех документов за январь 2026 года условие должно выглядеть так: ГДЕ Дата >= НАЧАЛОМЕСЯЦА(&Дата) И Дата < НАЧАЛОМЕСЯЦА(ДОБАВИТЬКДАТЕ(&Дата, МЕСЯЦ, 1)).
Такой подход, часто называемый «полуоткрытый интервал», гарантирует, что ни одна секунда не потеряется и не попадет в соседний период. Функция ДОБАВИТЬКДАТЕ позволяет динамически сдвигать границы периода на нужный интервал (месяц, квартал, год) без жесткой привязки к календарным числам.
⚠️ Внимание: Никогда не используйте функцию
КОНЕЦДНЯдля правой границы периода в сочетании с оператором «Меньше или равно». Это создаст риск потери документов, созданных в первые миллисекунды следующего дня, или дублирования данных при стыке периодов.
☑️ Проверка корректности периода
Вычисление разницы дат и арифметика времени
Иногда в запросе требуется не просто отфильтровать данные, но и вычислить возраст документа, срок оплаты или длительность процесса. Для этих целей в языке запросов 1С 8.3 предусмотрена функция РАЗНОСТЬДАТ. Она позволяет получить разницу между двумя датами в заданном измерении.
Синтаксис функции: РАЗНОСТЬДАТ(Дата1, Дата2, ТипРазности). Тип разности может принимать значения: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, ГОД.
Например, разница между 31 января и 1 февраля составит 1 день, но 0 месяцев. Разница между 31 января и 1 марта составит 1 месяц, несмотря на то, что прошло 29 или 30 дней. Это поведение необходимо учитывать при расчете пеней или сроков действия договоров.
Для более сложных расчетов, таких как добавление рабочего времени или учет выходных, встроенных функций в запросе нет. В таких случаях приходится использовать виртуальные таблицы календарей (если они реализованы в конфигурации) или выгружать данные для обработки во встроенном языке.
Функция РАЗНОСТЬДАТ возвращает целое число. Дробная часть отбрасывается. Для получения точного времени в секундах используйте тип разности СЕКУНДА и делите результат на 3600 для получения часов.
Оптимизация производительности при работе с датами
Использование функций над полями таблицы в условии отбора (ГДЕ) является одним из главных врагов производительности запросов. Когда вы пишете ГДЕ НАЧАЛОДНЯ(Таблица.Дата) = &Параметр, сервер баз данных часто вынужден перебирать все записи таблицы, применяя функцию к каждой дате, вместо того чтобы использовать индекс по полю Дата.
Чтобы выразить условие эффективно, необходимо перенести вычисления на сторону констант или параметров. Вместо применения функции к полю таблицы, измените параметр выборки. Правильный вариант: ГДЕ Таблица.Дата >= &НачалоДня И Таблица.Дата < &НачалоСледДня. В этом случае параметры &НачалоДня и &НачалоСледДня вычисляются один раз перед выполнением запроса.
Проверка плана выполнения запроса (F7 в Конфигураторе) покажет, используется ли индекс. Если в плане вы видите операцию «Table Scan» (полное сканирование таблицы) вместо «Index Seek» или «Index Range Scan», значит, условие сформулировано неоптимально. На больших объемах данных (миллионы записей) разница в скорости может составлять минуты против секунд.
⚠️ Внимание: Избегайте использования функций преобразования типов (например,
ЕСТЬNULLили приведение к строке) в условиях соединения таблиц (СОЕДИНЕНИЕ). Это практически гарантированно отключит использование индексов и приведет к деградации системы при росте базы.
Часто задаваемые вопросы (FAQ)
Как получить текущую дату в запросе 1С 8.3 без передачи параметров?
В языке запросов нет прямой функции «ТекущаяДата()» как во встроенном языке. Однако можно использовать спецсимвол & в сочетании с системными параметрами сеанса, если они настроены, либо передавать дату из кода. Самый надежный способ — сформировать параметр ТекущаяДата в объекте Запрос перед выполнением, присвоив ему значение ТекущаяДата() из встроенного языка.
Почему запрос не находит документы за сегодня, если я использую РАВНО?
Оператор РАВНО сравнивает дату с точностью до секунды. Если в параметре указано 25.10.2023 00:00:00, а документ создан в 10:15:30, они не равны. Используйте диапазон >= НАЧАЛОДНЯ(ТекущаяДата) И < НАЧАЛОДНЯ(ТекущаяДата + 1) для выборки всех документов за текущие сутки.
Можно ли в запросе 1С сложить две даты?
Нет, арифметическое сложение двух дат (Дата + Дата) не имеет физического смысла и не поддерживается синтаксисом. Можно складывать дату и число (количество дней, секунд), используя функцию ДОБАВИТЬКДАТЕ или оператор + с числом, но не две даты между собой.
Как правильно написать константу даты с временем в запросе?
Используйте формат &{ГГГГММДДЧЧММСС}. Например, для 5 мая 2026 года в 14 часов 30 минут запись будет выглядеть как &{20260505143000}. Если время не указано, оно считается нулевым.