Работа с датами в запросах 1С:Предприятие — одна из самых частых задач при разработке отчётов, обработок и аналитических выборок. Неправильно указанная дата может привести к пустому результату, ошибкам выполнения или некорректной фильтрации данных. В этой статье разберём все способы указания дат: от простых литералов до динамических параметров, а также нюансы работы с временными интервалами и функциями даты.

Особенность языка запросов 1С в том, что он поддерживает как стандартный SQL-подобный синтаксис, так и уникальные конструкции, специфичные для платформы. Например, здесь нет привычного TO_DATE() как в Oracle, но зато есть гибкие функции вроде НАЧАЛОПЕРИОДА() или КОНЕЦДНЯ(). Если вы только начинаете осваивать запросы или хотите систематизировать знания — этот материал поможет избежать типичных ошибок и оптимизировать код.

1. Базовый синтаксис: как указать дату напрямую в запросе

Самый простой способ — использовать литерал даты, который записывается в формате 'ГГГГ-ММ-ДД' или 'ГГГГ-ММ-ДД ЧЧ:ММ:СС'. Например, чтобы выбрать документы за конкретный день, достаточно написать:

ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

Документ.Дата КАК Дата

ИЗ

Документ.ПоступлениеТоваров КАК Документ

ГДЕ

Документ.Дата = '2026-10-15'

Важно: автоматически преобразует строковый литерал в тип Дата, но только если формат соответствует стандарту ISO 8601. Попытка указать дату в формате '15.10.2026' приведёт к ошибке! Также учитывайте, что время по умолчанию будет 00:00:00, если его явно не указать.

  • 📅 Литерал без времени: '2026-10-15' — соответствует началу дня (00:00:00).
  • ⏰ Литерал с временем: '2026-10-15 14:30:00' — точная метка времени.
  • 🌍 Часовой пояс: в даты хранятся без привязки к поясу, но при выводе могут корректироваться по настройкам пользователя.
⚠️ Внимание: Если в запросе используется литерал даты с временем (например, '2026-10-15 23:59:59'), а в базе данные хранятся с миллисекундами, сравнение может не сработать из-за округления. В таких случаях лучше использовать функции НАЧАЛОДНЯ() или КОНЕЦДНЯ().

2. Использование параметров запроса для гибкой фильтрации

Жёсткое указание даты в коде запроса не всегда удобно — часто требуется передавать её динамически из формы или переменной. Для этого в предусмотрены параметры запроса, которые обозначаются символом &. Например:

ВЫБРАТЬ

Документ.Ссылка,

Документ.Дата

ИЗ

Документ.РеализацияТоваров КАК Документ

ГДЕ

Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода

Чтобы передать значение параметра из кода , используйте метод УстановитьПараметр():

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Дата = &МойПараметр";

Запрос.УстановитьПараметр("МойПараметр", ТекущаяДата());

Результат = Запрос.Выполнить();

Преимущество параметров в том, что они:

  • 🔄 Позволяют повторно использовать один запрос с разными данными.
  • 🛡️ Защищают от SQL-инъекций (в отличие от конкатенации строк).
  • ⚡ Ускоряют выполнение за счёт предварительной компиляции плана запроса.
📊 Как вы обычно передаёте даты в запросы 1С?
Жёстко прописываю литералы
Использую параметры (&)
Генерирую строку динамически
Другое

3. Функции работы с датами в запросах 1С

1С:Предприятие предоставляет набор встроенных функций для манипуляции датами прямо в тексте запроса. Они помогают избежать ручного вычисления границ периодов или преобразования форматов. Вот ключевые из них:

Функция Описание Пример использования
ТЕКУЩАЯДАТА() Возвращает текущую дату и время на сервере. ГДЕ Дата > ТЕКУЩАЯДАТА() - 30 (за последние 30 дней)
НАЧАЛОПЕРИОДА(<Дата>, <Тип>) Возвращает начало периода (день, месяц, квартал, год). НАЧАЛОПЕРИОДА(&ДатаДок, "МЕСЯЦ")
КОНЕЦПЕРИОДА(<Дата>, <Тип>) Аналогично, но возвращает конец периода. КОНЕЦПЕРИОДА(ТЕКУЩАЯДАТА(), "КВАРТАЛ")
ДОБАВИТЬМЕСЯЦ(<Дата>, <Количество>) Сдвигает дату на указанное число месяцев. ДОБАВИТЬМЕСЯЦ(&Дата, -1) (предыдущий месяц)

Пример использования функций для выборки данных за текущий квартал:

ВЫБРАТЬ

Документ.Номер,

Документ.Сумма

ИЗ

Документ.ЗаказПокупателя КАК Документ

ГДЕ

Документ.Дата МЕЖДУ НАЧАЛОПЕРИОДА(ТЕКУЩАЯДАТА(), "КВАРТАЛ")

И КОНЕЦПЕРИОДА(ТЕКУЩАЯДАТА(), "КВАРТАЛ")

⚠️ Внимание: Функция ТЕКУЩАЯДАТА() возвращает дату и время на момент выполнения запроса, а не на момент компиляции текста. Если запрос выполняется долго, значение может отличаться от ожидаемого.

Убедиться, что тип периода ("ДЕНЬ", "МЕСЯЦ") написан заглавными буквами|

Проверить, что функция применяется к полю типа Дата, а не к строке|

Использовать НАЧАЛОПЕРИОДА/КОНЕЦПЕРИОДА для интервалов вместо ручного вычитания секунд|

Тестировать запрос с крайними датами (например, 31 декабря)

-->

4. Работа с интервалами и сравнение дат

Часто требуется выбрать данные за диапазон дат, например, за месяц или между двумя произвольными датами. Для этого используют операторы МЕЖДУ, >, < и их комбинации. Однако здесь есть нюансы:

  • 📊 МЕЖДУ включает обе границы: Дата МЕЖДУ '2026-01-01' И '2026-01-31' вернёт и 1, и 31 января.
  • ⏳ Для выборки "с начала дня" до "конца дня" используйте:
    Дата >= НАЧАЛОДНЯ(&Начало) И Дата < НАЧАЛОДНЯ(&Конец) + 86400
  • 🔄 Для исключения границ: Дата > '2026-01-01' И Дата < '2026-02-01' (январь без 1 февраля).

Типичная ошибка — забыть про время при сравнении. Например, запрос ГДЕ Дата = '2026-10-15' не вернёт документы, созданные 15 октября после 00:00:00, если в базе хранятся точные метки времени. Решение:

ГДЕ Дата >= НАЧАЛОДНЯ('2026-10-15')

И Дата < НАЧАЛОДНЯ('2026-10-16')

Почему не работает сравнение с точной датой?

При хранении даты с временем (например, '2026-10-15 14:30:00') сравнение с литералом '2026-10-15' (который эквивалентен '2026-10-15 00:00:00') вернёт ЛОЖЬ. Поэтому для выборки по календарному дню всегда используйте интервал от начала до конца дня.

5. Динамические даты: относительные периоды

В отчётах часто нужны данные за "последнюю неделю", "прошлый месяц" или "текущий квартал". Вместо жёсткого указания дат удобнее использовать относительные выражения. Например:

// За последние 7 дней (включая сегодня)

ГДЕ Дата >= ТЕКУЩАЯДАТА() - 7

// За предыдущий месяц

ГДЕ Дата МЕЖДУ НАЧАЛОПЕРИОДА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -1), "МЕСЯЦ")

И КОНЕЦПЕРИОДА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -1), "МЕСЯЦ")

// За текущий год

ГДЕ Дата >= НАЧАЛОПЕРИОДА(ТЕКУЩАЯДАТА(), "ГОД")

Для более сложных сценариев (например, "последний рабочий день месяца") можно комбинировать функции:

ГДЕ Дата = КОНЕЦПЕРИОДА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -1), "МЕСЯЦ")

Критическая особенность: функции ДОБАВИТЬМЕСЯЦ() и ДОБАВИТЬГОД() корректно обрабатывают переходы между месяцами разной длины (например, 31 января + 1 месяц = 28/29 февраля), в отличие от ручного прибавления дней.

6. Преобразование строк в даты и обратно

Иногда даты хранятся в базе как строки (например, в внешних источниках или устаревших конфигурациях). Чтобы их сравнить с полями типа Дата, нужно преобразовать формат. Для этого используйте функцию ДАТАВРЕМЯ():

ВЫБРАТЬ

Таблица.СтрокаДата КАК СтрокаДата,

ДАТАВРЕМЯ(Таблица.СтрокаДата КАК Строка, "ДФ=dd.MM.yyyy") КАК Дата

ИЗ

ВнешняяТаблица КАК Таблица

Обратное преобразование (дата в строку) выполняется функцией ФОРМАТ():

ВЫБРАТЬ

ФОРМАТ(Документ.Дата, "ДФ=dd.MM.yyyy HH:mm") КАК ФорматированнаяДата

ИЗ

Документ.Заказ КАК Документ

  • 📝 Формат "ДФ=dd.MM.yyyy" — стандартный для России.
  • 🌐 Для международного формата используйте "ДФ=yyyy-MM-dd".
  • ⏱️ Чтобы включить время: "ДФ=dd.MM.yyyy HH:mm:ss".
⚠️ Внимание: При преобразовании строк в даты строго проверяет соответствие формату. Если строка содержит некорректные данные (например, "31.02.2026"), запрос завершится с ошибкой. Для обработки таких случаев используйте конструкцию ВЫРАЗИТЬ() с проверкой:
ВЫБРАТЬ

ВЫРАЗИТЬ(ДАТАВРЕМЯ(Таблица.СтрокаДата КАК Строка, "ДФ=dd.MM.yyyy") КАК Дата) КАК Дата

ИЗ

ВнешняяТаблица КАК Таблица

ГДЕ

НЕ Таблица.СтрокаДата ЕСТЬ NULL

7. Оптимизация запросов с датами: индексы и планы выполнения

Запросы с фильтрацией по датам могут работать медленно, если:

  • 🐢 Поле даты не проиндексировано в базе.
  • 🔍 Используются функции над полем (например, ГДЕ ГОД(Дата) = 2026), что блокирует использование индекса.
  • 📈 Диапазон дат слишком широкий (например, за 10 лет).

Рекомендации по оптимизации:

  1. Всегда фильтруйте по оригинальному полю даты, а не по его частям:
    // Плохо (индекс не используется):
    

    ГДЕ ГОД(Дата) = 2026 И МЕСЯЦ(Дата) = 10

    // Хорошо:

    ГДЕ Дата МЕЖДУ '2026-10-01' И '2026-10-31'

  2. Для больших периодов разбивайте запрос на подзапросы или используйте ИНДЕКСИРОВАТЬ ПО (в последних версиях платформы).
  3. Проверяйте план выполнения запроса в Консоли запросов (меню Все функции → План запроса).
💡

Если запрос с датами выполняется долго, попробуйте добавить в условие И Дата < ТЕКУЩАЯДАТА() + 365 (или другой разумный лимит), чтобы ограничить диапазон поиска по умолчанию.

8. Типичные ошибки и как их избежать

Даже опытные разработчики иногда сталкиваются с неожиданными проблемами при работе с датами в . Вот наиболее распространённые ошибки:

Ошибка Причина Решение
Запрос не возвращает данные за текущий день Сравнение с '2026-10-15' не учитывает время документа. Использовать НАЧАЛОДНЯ() и КОНЕЦДНЯ().
Ошибка "Некорректное значение параметра" Параметр передан как строка, а не как Дата. Преобразовать значение: Запрос.УстановитьПараметр("Дата", Дата(СтрокаДата)).
Медленное выполнение на больших базах Отсутствует индекс по полю даты или используются функции над полем. Добавить индекс или переписать условие.
Неправильный результат при добавлении месяцев Ручное прибавление дней не учитывает длину месяца. Использовать ДОБАВИТЬМЕСЯЦ().

Ещё одна ловушка — разница часовых поясов. Если сервер и клиент находятся в разных поясах, ТЕКУЩАЯДАТА() на сервере может отличаться от локального времени пользователя. Чтобы избежать путаницы:

  • 🕒 Явно указывайте пояс в отчётах (например, "МСК").
  • 📡 Для критичных операций используйте ТЕКУЩАЯДАТАСЕАНСА() — она возвращает дату с учётом сеанса пользователя.
💡

Всегда тестируйте запросы с датами на граничных значениях: начало/конец месяца, високосные годы, переход на зимнее/летнее время (если актуально).

FAQ: Частые вопросы по работе с датами в запросах 1С

Как выбрать документы за вчерашний день?

Используйте комбинацию функций:

ГДЕ Дата МЕЖДУ НАЧАЛОДНЯ(ТЕКУЩАЯДАТА() - 1)

И КОНЕЦДНЯ(ТЕКУЩАЯДАТА() - 1)

Или короче:

ГДЕ Дата >= НАЧАЛОДНЯ(ТЕКУЩАЯДАТА()) - 86400

И Дата < НАЧАЛОДНЯ(ТЕКУЩАЯДАТА())

Почему запрос с параметром даты возвращает пустой результат, хотя данные есть?

Вероятные причины:

  1. Параметр передан как строка (например, "15.10.2026"), а не как Дата. Проверьте тип: ТипЗнч(&ДатаПараметр) = Тип("Дата").
  2. В базе даты хранятся с временем, а сравнение идёт без учёта времени. Используйте НАЧАЛОДНЯ().
  3. Опечатка в имени параметра (регистр важен!). Убедитесь, что в коде и тексте запроса имена совпадают.
Как выбрать данные за последний квартал, не указывая даты явно?

Используйте относительные функции:

ГДЕ Дата МЕЖДУ НАЧАЛОПЕРИОДА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -3), "КВАРТАЛ")

И КОНЕЦПЕРИОДА(ДОБАВИТЬМЕСЯЦ(ТЕКУЩАЯДАТА(), -3), "КВАРТАЛ")

Для текущего квартала замените -3 на 0.

Можно ли в запросе 1С использовать конструкцию BETWEEN как в SQL?

Да, оператор МЕЖДУ в полностью аналогичен BETWEEN в SQL и включает обе границы. Пример:

ГДЕ Дата МЕЖДУ '2026-01-01' И '2026-12-31'

Это эквивалентно:

ГДЕ Дата >= '2026-01-01' И Дата <= '2026-12-31'
Как сравнить только дату без времени, если в базе хранится ДатаВремя?

Используйте функцию НАЧАЛОДНЯ() для обеих частей сравнения:

ГДЕ НАЧАЛОДНЯ(Документ.Дата) = НАЧАЛОДНЯ('2026-10-15')

Это гарантирует, что время будет проигнорировано.