Разработка и Конфигурация · 11 мин
Как получить даты в запросе 1С
Как работать с датами в запросе 1С: литерал ДАТАВРЕМЯ, функции НАЧАЛОПЕРИОДА, РАЗНОСТЬДАТ, ДОБАВИТЬКДАТЕ, отборы по периоду и типичные ошибки.
Работа с датами — одна из самых частых задач при написании запросов в 1С. Период, дата документа, границы отчётного интервала, срок исполнения — всё это хранится в базе как дата-время, и язык запросов предоставляет для этого специальный набор конструкций: литерал ДАТАВРЕМЯ, функции выделения части даты, сдвига и вычисления разности.
Ошибка при обработке дат обычно выглядит безобидно — запрос выполняется, но возвращает пустой результат или лишние строки. Причина почти всегда одна: несовпадение типов (дата против строки), неучтённое время внутри даты или неверная граница периода. Ниже разобраны все основные способы получить и обработать дату в запросе, с примерами кода и проверками результата.
Материал ориентирован на встроенный язык запросов 1С:Предприятие 8.3. Конструкции работают одинаково в консоли запросов, в коде модулей и в схеме компоновки данных, если не оговорено иное.
Литерал ДАТАВРЕМЯ: как задать конкретную дату в тексте запроса
Прямо в тексте запроса дата записывается литералом ДАТАВРЕМЯ(2026, 1, 15, 0, 0, 0). Аргументы идут в порядке: год, месяц, день, час, минута, секунда. Время указывать не обязательно — если его опустить, оно будет равно началу дня (00:00:00).
ВЫБРАТЬ
Продажи.Ссылка,
Продажи.Дата
ИЗ
Документ.РеализацияТоваровУслуг КАК Продажи
ГДЕ
Продажи.Дата >= ДАТАВРЕМЯ(2026, 1, 1)
Литерал удобен для отладки в консоли запросов, но в рабочем коде жёстко зашитые даты почти всегда вредны: при смене периода придётся править текст запроса. Поэтому в прикладном коде даты передают параметрами, а литерал оставляют для тестов и разовых проверок.
Частая ошибка — попытка написать дату строкой: ГДЕ Дата = "15.01.2026". Запрос не сравнивает дату со строкой автоматически, и результат будет пустым или запрос завершится ошибкой несоответствия типов.
Передача даты через параметр запроса
Стандартный способ — объявить параметр и присвоить ему значение типа Дата перед выполнением запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Продажи
|ГДЕ
| Продажи.Дата МЕЖДУ &НачалоПериода И &КонецПериода";
Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(ДатаОкончания));
Результат = Запрос.Выполнить();
Ключевой момент — функции НачалоДня() и КонецДня() встроенного языка. Дата в 1С всегда содержит время с точностью до секунды. Если пользователь выбрал на форме «31.01.2026», в переменной окажется 31.01.2026 0:00:00, и документы, проведённые днём 31 января, не попадут в диапазон. КонецДня() возвращает 23:59:59, что закрывает весь день.
Функции работы с датой в языке запросов
Язык запросов содержит встроенные функции, которые позволяют обрабатывать даты без выгрузки результата в код. Основные из них:
НАЧАЛОПЕРИОДА(Дата, Период)— возвращает начало указанного периода: ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД;КОНЕЦПЕРИОДА(Дата, Период)— конец периода с точностью до секунды;ДОБАВИТЬКДАТЕ(Дата, Тип, Количество)— сдвиг даты на заданное число секунд, дней, месяцев и т.д.;РАЗНОСТЬДАТ(Дата1, Дата2, Тип)— разница между датами в указанных единицах;ГОД(Дата),МЕСЯЦ(Дата),ДЕНЬ(Дата),ЧАС(Дата),МИНУТА(Дата),СЕКУНДА(Дата)— извлечение частей даты;ДЕНЬНЕДЕЛИ(Дата),ДЕНЬГОДА(Дата),НЕДЕЛЯГОДА(Дата)— календарные характеристики.
Пример: сгруппировать продажи по месяцам и вычислить, сколько дней прошло с момента отгрузки:
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(Продажи.Период, МЕСЯЦ) КАК Месяц,
СУММА(Продажи.СуммаОборот) КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты КАК Продажи
СГРУППИРОВАТЬ ПО
НАЧАЛОПЕРИОДА(Продажи.Период, МЕСЯЦ)
УПОРЯДОЧИТЬ ПО
Месяц
ВЫБРАТЬ
Заказ.Ссылка,
РАЗНОСТЬДАТ(Заказ.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейСОформления
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
РАЗНОСТЬДАТ(Заказ.Дата, &ТекущаяДата, ДЕНЬ) > 7Как получить текущую дату в запросе
В языке запросов нет функции «текущая дата» — её нужно передать параметром из кода. Перед выполнением запроса получите значение через ТекущаяДатаСеанса() и установите его как параметр:
Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса());
Использовать следует именно ТекущаяДатаСеанса(), а не устаревшее ТекущаяДата(): функция сеанса учитывает часовой пояс информационной базы и корректно работает в клиент-серверном режиме, где время клиента и сервера могут различаться.
В схеме компоновки данных для отчётов на СКД есть альтернатива — стандартные параметры периода и выражения языка выражений СКД, но внутри текста запроса источника данных правило то же: дата приходит параметром.
Отбор по периоду и границы интервалов
При отборе документов за период надёжнее всего конструкция МЕЖДУ &Начало И &Конец с правильно подготовленными границами. Альтернатива — приведение даты документа к началу дня и сравнение с границами без времени, но это заставляет СУБД вычислять функцию для каждой строки и мешает использованию индексов.
Сравнение вариантов отбора по периоду
Самый быстрый вариант, использует индекс по дате. Требует корректной конечной границы (КонецДня)
Удобен, когда границы заданы без времени, но вычисление функции для каждой строки замедляет запрос на больших таблицах
Оптимален для регистров: отбор по периоду выполняется на уровне виртуальной таблицы до соединений
Для регистров накопления и сведений период лучше задавать в параметрах виртуальной таблицы, а не в секции ГДЕ: тогда СУБД сначала отберёт нужный диапазон, а потом выполнит соединения. Это заметно быстрее на больших объёмах данных.
Как проверить результат
В выборку попадают документы, проведённые в любое время последнего дня
Документы последнего дня после 00:00:00 отсутствуют — конечная граница задана как начало дня
Колонка имеет тип Дата, сортировка и группировка работают корректно
Даты выглядят как строки, сортировка идёт по алфавиту — значение было преобразовано в строку в запросе
Документ ровно в 00:00:00 первого дня и в 23:59:59 последнего присутствуют
Граничные записи теряются — проверьте включительность МЕЖДУ и точность параметров
Преобразование даты в строку и обратно
В языке запросов нет функции форматирования даты в строку — ПРЕДСТАВЛЕНИЕ() возвращает представление, но его формат зависит от настроек и не предназначен для дальнейшей обработки. Если нужна строка определённого формата, преобразование делают уже в коде после выгрузки результата через Формат(Дата, "ДФ=dd.MM.yyyy").
Обратная задача — получить дату из строки — в запросе напрямую не решается. Строку преобразуют в дату на встроенном языке через Дата() с разбором компонентов или через функции работы со строками, и только потом передают в запрос параметром. Это ограничение важно учитывать при загрузке данных из внешних файлов: сначала парсинг в коде, затем запрос.
- 1Определите, откуда приходит дата: константа в тексте (ДАТАВРЕМЯ), параметр из кода или поле таблицы
- 2Для параметров из пользовательского ввода примените НачалоДня()/КонецДня() на стороне кода
- 3В запросе используйте МЕЖДУ для диапазонов и функции НАЧАЛОПЕРИОДА/РАЗНОСТЬДАТ для вычислений
- 4Проверьте граничные записи: первый и последний день периода должны попадать в результат полностью
- 5Для регистров перенесите отбор по периоду в параметры виртуальной таблицы
Частые ошибки и ограничения
Кроме уже упомянутых проблем со временем и типами, встречаются менее очевидные ситуации. Пустая дата в 1С — это ДАТАВРЕМЯ(1, 1, 1), и сравнение с NULL её не отловит: для проверки незаполненной даты используют Дата = ДАТАВРЕМЯ(1, 1, 1), а для отсутствующего значения в соединении — ЕСТЬ NULL.
Функция РАЗНОСТЬДАТ считает целое число полных единиц: разница между 31 января и 1 февраля в месяцах равна нулю, хотя прошёл один день. Для расчётов «человек понял бы так» иногда нужно комбинировать единицы или сначала привести обе даты к началу дня.
Ещё одно ограничение: в запросе нельзя вызывать функции встроенного языка (НачалоДня(), ТекущаяДатаСеанса()) — все такие вычисления выполняются до формирования текста запроса, а внутри доступны только функции языка запросов.
Что важно запомнить
Дата в запросе задаётся литералом ДАТАВРЕМЯ или параметром; текущая дата передаётся через параметр с ТекущаяДатаСеанса(). Для периодов используйте МЕЖДУ с границами НачалоДня/КонецДня, для вычислений — НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, РАЗНОСТЬДАТ и ДОБАВИТЬКДАТЕ. Не сравнивайте даты со строками и не забывайте про время внутри даты.
Частые вопросы
Как получить в запросе только дату без времени?
Используйте НАЧАЛОПЕРИОДА(Дата, ДЕНЬ) — функция вернёт ту же дату со временем 00:00:00. Полностью «отрезать» время нельзя, так как тип Дата в 1С всегда содержит время; при необходимости отображения без времени форматируйте значение при выводе через Формат() в коде или настройки поля в СКД.
Как отобрать документы за текущий месяц?
Передайте в запрос два параметра: НачалоМесяца(ТекущаяДатаСеанса()) и КонецМесяца(ТекущаяДатаСеанса()), вычисленные в коде, и используйте условие Дата МЕЖДУ &Начало И &Конец. Вычислять границы функциями запроса от параметра тоже можно: НАЧАЛОПЕРИОДА(&ТекущаяДата, МЕСЯЦ).
Почему сравнение Дата = &Дата не находит документ?
Почти всегда причина во времени: документ проведён, например, в 14:32:05, а параметр содержит 00:00:00. Сравнивайте диапазоном за день (МЕЖДУ НачалоДня И КонецДня) или приводите обе стороны к началу дня функцией НАЧАЛОПЕРИОДА.
Как проверить, что дата не заполнена?
Пустая дата равна ДАТАВРЕМЯ(1, 1, 1). Условие в запросе: Дата = ДАТАВРЕМЯ(1, 1, 1). Если поле может быть NULL из-за левого соединения, дополнительно проверяйте Поле ЕСТЬ NULL — это разные ситуации, и одно условие другое не заменяет.
Можно ли прибавить к дате несколько дней прямо в запросе?
Да, функцией ДОБАВИТЬКДАТЕ(Дата, ДЕНЬ, 5). Поддерживаются единицы СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД. Для вычитания передайте отрицательное количество. Складывать дату с числом оператором «+» нельзя — это вызовет ошибку.
Как посчитать возраст или стаж в запросе?
Базовый вариант — РАЗНОСТЬДАТ(ДатаРождения, &ТекущаяДата, ГОД), но он считает полные годы между календарными отметками и может дать погрешность в год, если день рождения ещё не наступил. Для точного расчёта комбинируйте РАЗНОСТЬДАТ по годам и месяцам с поправкой через ВЫБОР, либо выполняйте расчёт в коде после выгрузки результата.