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

В этой статье мы разберём все аспекты работы с датами в языке запросов 1С — от базового синтаксиса до оптимизации сложных конструкций. Вы узнаете, как правильно указывать даты в условиях ГДЕ, использовать функции для работы с временными интервалами, избегать типовых ошибок и ускорять выполнение запросов. Материал будет полезен как начинающим разработчикам, так и опытным специалистам, которые хотят систематизировать свои знания.

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

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

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

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

Документ.Дата = ДАТАВРЕМЯ(2026, 05, 15)

Обратите внимание: функция ДАТАВРЕМЯ() более надёжна, чем строковый литерал, так как автоматически преобразует значение в внутренний формат 1С. Альтернативный вариант — использование параметра запроса:

ЗАПРОС.УстановитьПараметр("НачалоПериода", НачалоДня(ТекущаяДата()));

Это особенно удобно, когда дата формируется динамически в коде программы. Главное правило: никогда не передавайте даты в запрос как строки без явного приведения типа — это чревато ошибками при изменении региональных настроек базы.

  • 📅 Литерал даты: '2026-05-15' — простой, но зависит от настроек языка
  • Функция ДАТАВРЕМЯ(): ДАТАВРЕМЯ(2026, 5, 15, 0, 0, 0) — надёжнее для серверных запросов
  • 🔄 Параметры запроса: УстановитьПараметр("ДатаОт", НачалоМесяца(ТекущаяДата())) — лучший выбор для динамических дат
ГДЕ Документ.Дата = НАЧАЛОДНЯ(ДАТАВРЕМЯ(2026, 5, 15))-->

2. Фильтрация по диапазону дат: между, больше/меньше, в списке

Чаще всего даты используются для отбора документов за определённый период. Рассмотрим основные способы фильтрации:

1. Диапазон между двумя датами (включительно):

ГДЕ Документ.Дата МЕЖДУ ДАТАВРЕМЯ(2026, 01, 01)

И ДАТАВРЕМЯ(2026, 01, 31)

2. Отбор по "больше/меньше" (исключая граничные даты):

ГДЕ Документ.Дата >= ДАТАВРЕМЯ(2026, 01, 01)

И Документ.Дата < ДАТАВРЕМЯ(2026, 02, 01)

3. Даты в списке (например, только по понедельникам):

ГДЕ ДЕНЬНЕДЕЛИ(Документ.Дата) В (1)  // 1 = понедельник

Важный нюанс: при работе с МЕЖДУ граничные даты включаются в результат, тогда как при использовании >= и < верхняя граница исключается. Это часто становится причиной ошибок в отчётах, где важна точность границ периода.

Конструкция Пример Включает границы? Применение
МЕЖДУ ... И ... МЕЖДУ '2026-01-01' И '2026-01-31' Да Отчёты за полный месяц
>= и < >= '2026-01-01' И < '2026-02-01' Нет (верхняя) Аналитика по дням без наложения
ДЕНЬНЕДЕЛИ() В () ДЕНЬНЕДЕЛИ(Дата) В (1, 7) Фильтр по дням недели
📊 Какой способ фильтрации по датам вы используете чаще?
МЕЖДУ ... И
>= и <
ДЕНЬНЕДЕЛИ()
Параметры запроса

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

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

  • 📆 НАЧАЛОПЕРИОДА() — возвращает начало дня/недели/месяца/квартала/года:
    НАЧАЛОПЕРИОДА(Документ.Дата, "МЕСЯЦ")
  • КОНЕЦПЕРИОДА() — аналог НАЧАЛОПЕРИОДА, но для конца периода:
    КОНЕЦПЕРИОДА(ДАТАВРЕМЯ(2026, 5, 15), "КВАРТАЛ")
  • 🔄 ДОБАВИТЬКДАТЕ() — прибавляет дни/месяцы/годы:
    ДОБАВИТЬКДАТЕ(Документ.Дата, "ДЕНЬ", 7)
  • 📊 РАЗНОСТЬДАТ() — вычисляет разницу между датами в днях/месяцах:
    РАЗНОСТЬДАТ("ДЕНЬ", Документ.Дата, ТЕКУЩАЯДАТА())

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

ВЫБРАТЬ

НАЧАЛОПЕРИОДА(Документ.Дата, "МЕСЯЦ") КАК Месяц,

СУММА(Документ.СуммаДокумента) КАК Итого

ИЗ

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

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

НАЧАЛОПЕРИОДА(Документ.Дата, "МЕСЯЦ")

Как работают функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА с кварталами?

Функция НАЧАЛОПЕРИОДА(Дата, "КВАРТАЛ") возвращает первую дату квартала (1 января, 1 апреля, 1 июля или 1 октября), а КОНЕЦПЕРИОДА() — последнюю (31 марта, 30 июня и т.д.). Важно: в 1С кварталы всегда считаются с января, независимо от налогового периода организации.

При работе с ДОБАВИТЬКДАТЕ() будьте осторожны: при добавлении месяцев функция корректно обрабатывает конец месяца. Например, ДОБАВИТЬКДАТЕ('2026-01-31', "МЕСЯЦ", 1) вернёт '2026-02-29' (а не 31 февраля!).

💡

Функции НАЧАЛОПЕРИОДА() и КОНЕЦПЕРИОДА() — самый надёжный способ группировки по календарным интервалам, так как они учитывают все нюансы календаря (включая високосные годы).

4. Типовые ошибки при работе с датами и как их избежать

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

⚠️ Внимание: Если вы используете строковые литералы дат ('2026-05-15') без явного приведения типа, запрос может работать неправильно при изменении региональных настроек сервера 1С. Всегда используйте ДАТАВРЕМЯ() или параметры.
  • Сравнение даты со строкой:

    Ошибка: ГДЕ Документ.Дата = "15.05.2026"

    Правильно: ГДЕ Документ.Дата = ДАТАВРЕМЯ(2026, 5, 15)

  • Неучёт времени в датах:

    Ошибка: ГДЕ Документ.Дата = ТЕКУЩАЯДАТА() (не сработает для документов, созданных сегодня после 00:00)

    Правильно: ГДЕ НАЧАЛОДНЯ(Документ.Дата) = НАЧАЛОДНЯ(ТЕКУЩАЯДАТА())

  • Неверный порядок аргументов в ДАТАВРЕМЯ():

    Ошибка: ДАТАВРЕМЯ(15, 5, 2026) (день-месяц-год вместо год-месяц-день)

    Правильно: ДАТАВРЕМЯ(2026, 5, 15)

Ещё одна распространённая проблема — несоответствие типов при сравнении. Например, если поле в базе имеет тип "Дата", а вы сравниваете его с параметром типа "Строка", 1С не выдаст ошибку, но результат будет некорректным. Всегда проверяйте типы полей в метаданных!

Все даты заданы через ДАТАВРЕМЯ() или параметры|Учтено время при сравнении дат (НАЧАЛОДНЯ)|Правильный порядок аргументов в функциях|Типы сравниваемых полей совпадают-->

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

Запросы с фильтрацией по датам могут тормозить, если не учтены особенности работы СУБД. Вот ключевые правила оптимизации:

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

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

ГДЕ МЕСЯЦ(Документ.Дата) = 5

лучше написать:

ГДЕ Документ.Дата >= ДАТАВРЕМЯ(2026, 5, 1)

И Документ.Дата < ДАТАВРЕМЯ(2026, 6, 1)

3. Ограничивайте объём выборки. Если вам нужны только документы за последний месяц, не запрашивайте весь регистр:

ГДЕ Документ.Дата >= НАЧАЛОМЕСЯЦА(ТЕКУЩАЯДАТА())

Для анализа производительности используйте ПЛАН ВЫПОЛНЕНИЯ в консоли запросов (Ctrl+Shift+Q). Это поможет выявить "узкие места".

Антипаттерн Проблема Оптимизированный вариант
ГДЕ ГОД(Дата) = 2026 Функция над полем блокирует использование индекса ГДЕ Дата >= '2026-01-01' И Дата < '2026-01-01'
ГДЕ ДЕНЬ(Дата) = 15 Полное сканирование таблицы ГДЕ Дата >= '2026-05-15' И Дата < '2026-05-16'
Выборка за 10 лет без ограничений Перегрузка памяти Разбивка на периоды или использование ПЕРВЫЕ 1000
ГДЕ Документ.Дата >= ДОБАВИТЬКДАТЕ(ТЕКУЩАЯДАТА(), "ДЕНЬ", -30)

Это эффективнее, чем вычислять разницу дат в условии.-->

6. Сложные сценарии: работа с временными интервалами и календарями

Иногда требуется учитывать нестандартные календари (например, рабочие дни) или сложные временные интервалы. Рассмотрим несколько нетривиальных задач:

1. Отбор только по рабочим дням (исключая выходные):

ГДЕ ДЕНЬНЕДЕЛИ(Документ.Дата) НЕ В (6, 7)  // 6=суббота, 7=воскресенье

2. Фильтрация по "рабочему времени" (например, с 9:00 до 18:00):

ГДЕ Документ.Дата >= ДАТАВРЕМЯ(2026, 5, 15, 9, 0, 0)

И Документ.Дата < ДАТАВРЕМЯ(2026, 5, 15, 18, 0, 0)

3. Расчёт количества рабочих дней между датами (требует кастомизации):

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

ВЫБРАТЬ

РАЗНОСТЬДАТ("ДЕНЬ", Документ.ДатаНачала, Документ.ДатаОкончания) + 1 -

(ВЫБОР

КОГДА ДЕНЬНЕДЕЛИ(Документ.ДатаНачала) = 6 ТОГДА 1

КОГДА ДЕНЬНЕДЕЛИ(Документ.ДатаНачала) = 7 ТОГДА 1

ИНАЧЕ 0

КОНЕЦ) КАК РабочиеДни

...

Для точного учёта праздников придётся создать справочник "Производственный календарь" и связать его с запросом через временную таблицу. Это актуально для расчёта зарплаты, графиков работы или логистических задач.

Как учитывать региональные праздники?

Если в вашей организации действуют региональные праздничные дни (например, в Татарстане — Ураза-Байрам), создайте справочник "ПраздничныеДни" с полем "Дата" и используйте его в запросе:

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПраздничныеДни КАК Праздники ПО Документ.Дата = Праздники.Дата

ГДЕ Праздники.Ссылка ЕСТЬ NULL

7. Интеграция с внешними системами: форматы дат и конвертация

При обмене данными между 1С и внешними системами (например, Excel, SQL-базами или REST API) часто возникают проблемы с форматами дат. Основные правила:

  • 🔄 Из 1С во внешнюю систему:

    Используйте Формат(Дата, "ДФ=yyyy-MM-dd") для универсального строкового представления.

  • 📅 Из внешней системы в 1С:

    Для строковых дат применяйте ДАТАВРЕМЯ(Год, Месяц, День) после парсинга.

  • 🗃️ Обмен с SQL:

    В Microsoft SQL Server используйте CONVERT(DATETIME, '2026-05-15', 120).

Пример конвертации даты из строки в формате DD.MM.YYYY:

Дата = ДАТАВРЕМЯ(

ЧИСЛО(ЛЕВ(СтрокаДата, 2)), // День

ЧИСЛО(СРЕД(СтрокаДата, 4, 2)), // Месяц

ЧИСЛО(ПРАВ(СтрокаДата, 4)) // Год

);

⚠️ Внимание: При обмене с Excel помните, что там даты хранятся как числа (количество дней с 1900 года). Используйте формулу =ДАТАЗНАЧ("15.05.2026") в Excel или функцию ДАТАВРЕМЯ() в 1С для корректного преобразования.

Для автоматизации обмена рекомендуем создать универсальную функцию-конвертер, которая будет учитывать форматы всех интегрируемых систем. Пример:

Функция СтрокаВДату(Значение, Формат = "DD.MM.YYYY") Экспорт

// Реализация парсинга строки в дату с учётом формата

КонецФункции

8. Практические примеры: готовые запросы для типовых задач

Разберём несколько готовых запросов, которые пригодятся в повседневной работе:

1. Продажи по дням за текущий месяц:

ВЫБРАТЬ

НАЧАЛОДНЯ(Документ.Дата) КАК Дата,

СУММА(Документ.СуммаДокумента) КАК Сумма

ИЗ

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

ГДЕ

Документ.Дата >= НАЧАЛОМЕСЯЦА(ТЕКУЩАЯДАТА())

И Документ.Дата < КОНЕЦМЕСЯЦА(ТЕКУЩАЯДАТА()) + 1

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

НАЧАЛОДНЯ(Документ.Дата)

УПОРЯДОЧИТЬ ПО

Дата

2. Среднее время обработки заказов:

ВЫБРАТЬ

СРЕДНЕЕ(

РАЗНОСТЬДАТ(

"ЧАС",

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

Документ.ДатаОплаты

)

) КАК СреднееВремяОбработки

3. Товары, не продававшиеся более 30 дней:

ВЫБРАТЬ РАЗЛИЧНЫЕ

Товар.Ссылка КАК Товар

ИЗ

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

ГДЕ

Товар.Ссылка НЕ В (

ВЫБРАТЬ РАЗЛИЧНЫЕ Товары.Ссылка

ИЗ Документ.РеализацияТоваровУслуг.Товары КАК Товары

ГДЕ Товары.Документ.Дата >= ТЕКУЩАЯДАТА() - 30

)

4. Документы, созданные в выходные:

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

ДЕНЬНЕДЕЛИ(Документ.Дата) В (6, 7) // 6=суббота, 7=воскресенье

Эти запросы можно использовать как основу для своих отчётов. Не забывайте адаптировать их под свою конфигурацию (именование полей и таблиц может отличаться!).

💡

Для ускорения повторяющихся отчётов сохраняйте часто используемые запросы в общих модулях или хранимых процедурах (если используется SQL-сервер).

FAQ: Ответы на частые вопросы

Как в запросе 1С получить первую и последнюю дату месяца?

Используйте функции НАЧАЛОМЕСЯЦА() и КОНЕЦМЕСЯЦА():

ВЫБРАТЬ

НАЧАЛОМЕСЯЦА(ТЕКУЩАЯДАТА()) КАК ПервыйДень,

КОНЕЦМЕСЯЦА(ТЕКУЩАЯДАТА()) КАК ПоследнийДень

Для произвольной даты замените ТЕКУЩАЯДАТА() на нужное значение.

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

Чаще всего это связано с:

  1. Отсутствием индекса на поле с датой;
  2. Использованием функций над полем в условии (например, ГОД(Дата) = 2026);
  3. Слишком большим периодом выборки (запросите только нужные данные).

Проверьте план выполнения запроса (Ctrl+Shift+Q) для точной диагностики.

Как в запросе получить текущую дату без времени?

Используйте комбинацию НАЧАЛОДНЯ(ТЕКУЩАЯДАТА()):

ГДЕ Документ.Дата >= НАЧАЛОДНЯ(ТЕКУЩАЯДАТА())

И Документ.Дата < НАЧАЛОДНЯ(ТЕКУЩАЯДАТА()) + 86400 // +1 день в секундах

Или проще:

ГДЕ НАЧАЛОДНЯ(Документ.Дата) = НАЧАЛОДНЯ(ТЕКУЩАЯДАТА())
Можно ли в запросе 1С сравнивать даты с учётом часового пояса?

В стандартных запросах 1С часовые пояса не учитываются — все даты хранятся в локальном времени сервера. Для работы с часовыми поясами потребуется:

  1. Хранить смещение в отдельном поле;
  2. Использовать внешние обработки или расширения;
  3. Для 1С:Enterprise рассмотреть механизм ВременнаяЗона (доступен в последних версиях).
Как в запросе получить количество дней между двумя датами?

Используйте функцию РАЗНОСТЬДАТ():

ВЫБРАТЬ

РАЗНОСТЬДАТ("ДЕНЬ", Документ.ДатаНачала, Документ.ДатаОкончания) КАК КоличествоДней

Для рабочих дней потребуется дополнительная логика (см. раздел про сложные сценарии).