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

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

Синтаксис констант даты и времени

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

Если вам необходимо указать не просто день, а конкретный момент времени, включая часы, минуты и секунды, формат усложняется. В этом случае после даты ставится пробел, а затем следует время в формате ЧЧ:ММ:СС. Например, запись '20231231 235959' укажет на последнюю секунду последнего дня года.

Существует также сокращенный синтаксис, позволяющий указывать только год или год с месяцем. Запись '2023' будет интерпретирована как начало года (1 января 00:00:00), а '202301' — как начало января. Однако для максимальной точности и избежания двусмысленности в сложных фильтрах рекомендуется всегда использовать полный формат ГГГГММДД. Это делает код более читаемым и предсказуемым для других разработчиков, поддерживающих вашу конфигурацию.

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

💡

Используйте полный восьмизначный формат даты (ГГГГММДД) даже для обозначения начала дня, чтобы избежать неявных преобразований типов и повысить читаемость кода запроса.

Использование диапазонов дат в условиях выбора

Наиболее частой задачей при написании запросов является выборка документов за определенный период. Для этого используются операторы сравнения >= (больше или равно) и < (меньше). Ключевой особенностью работы с диапазонами в 1С является то, что верхняя граница периода обычно задается как начало следующего интервала, а не конец текущего. Это связано с тем, что тип ДатаВремя включает в себя секунды, и попытка указать «конец дня» как 23:59:59 может привести к потере данных, если в системе существуют записи с более высокой точностью или если время было записано некорректно.

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

ГДЕ ДатаДокумента >= '20230101' И ДатаДокумента < '20230201'

Такой подход гарантирует, что будут выбраны все документы, созданные в течение января, независимо от того, в какую секунду они были проведены. Использование оператора <= с указанием конца дня (например, '20230131 235959') является менее надежным методом, так как требует точного знания максимальной возможной метки времени в системе.

При формировании динамических диапазонов в встроенном языке 1С (например, в обработчике формы) часто используется конструкция КонецДня() или КонецМесяца(). Однако при передаче таких значений в запрос через параметры необходимо помнить о типизации. Если вы передаете параметр в запрос, убедитесь, что в тексте запроса он используется корректно, а в коде языка 1С значение параметра имеет тип Дата. Ошибки часто возникают при попытке передать дату в виде строки, не преобразовав её предварительно функцией Дата().

☑️ Проверка диапазона дат

Выполнено: 0 / 4

Работа с параметрами запроса и типизация

В реальных задачах жесткая прописка дат в тексте запроса используется редко, так как делает код негибким. Гораздо эффективнее использовать параметры, которые подставляются в запрос в момент его выполнения. Для обозначения параметра в тексте запроса используется символ двоеточия, например :НачалоПериода. При этом в самом тексте запроса не нужно указывать кавычки для параметра, система сама подставит значение в правильном формате.

Однако, если вы формируете запрос динамически или используете конструктор, важно следить за тем, чтобы значение параметра в коде 1С действительно было датой. Попытка передать строку вида "01.01.2023" в параметр типа Дата вызовет ошибку преобразования типов. Для безопасной работы рекомендуется явно создавать объекты даты:

Запрос.УстановитьПараметр("НачалоПериода", Дата(2023, 01, 01));

Существует нюанс при работе с неопределенными значениями. Если параметр даты может быть пустым (например, пользователь не выбрал период), и вы хотите выбрать все записи в этом случае, логика условия должна быть построена аккуратно. Часто используется конструкция ИСТИНА или проверка на заполненность параметра перед добавлением условия в текст запроса. Игнорирование этого момента может привести к тому, что при пустом параметре запрос вернет пустой результат вместо всех данных.

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

📊 Как вы чаще всего передаете даты в запрос?
Жестко в тексте запроса
Через параметры
Через функцию ЗНАЧЕНИЕ()
Динамическим формированием текста

Сравнение дат и временных меток

При сравнении полей типа ДатаВремя с константами важно понимать, как платформа обрабатывает недостающие компоненты времени. Если вы сравниваете поле базы данных, содержащее время 12:30:45, с константой '20230101' (что равно 00:00:00), результат сравнения будет зависеть от оператора. Запись Дата = '20230101' найдет только те документы, которые были созданы ровно в полночь. Это крайне редкая ситуация, и использование оператора равенства для дат без указания времени — частая ошибка новичков.

Для корректного поиска документов, созданных в конкретный день, всегда используйте диапазон, о котором говорилось выше. Если же вам нужно найти документы, созданные в определенное время с точностью до минуты, можно использовать усеченные константы. Например, '20230101 1230' будет означать 12:30:00. Платформа автоматически дополнит секунды нулями. Это удобно для поиска событий, привязанных к расписанию или регламентным заданиям.

Особое внимание следует уделить сравнению с текущим моментом времени. Функция СЕГОДНЯ() в запросах возвращает текущую дату с обнуленным временем (начало дня). Если вам нужно сравнить дату документа с текущим моментом «прямо сейчас», используйте функцию ТЕКУЩАЯДАТА() (если доступна в контексте) или передавайте текущее время из кода 1С функцией ТекущаяДата() в качестве параметра. Прямое использование системных функций времени внутри текста запроса 1С ограничено и зависит от версии платформы.

⚠️ Внимание: Оператор равенства (=) для типа ДатаВремя требует полного совпадения до секунды. Никогда не используйте его для поиска документов «за сегодня», если не обнулили время в сравниваемых значениях заранее.

В некоторых случаях требуется игнорировать время при сравнении. Для этого в запросе можно использовать функцию НАЧАЛОДНЯ(). Конструкция НАЧАЛОДНЯ(ДатаДокумента) = НАЧАЛОДНЯ(&:ТекущаяДата) позволит найти все документы текущего дня, независимо от времени их проведения. Это более производительный способ по сравнению с построением диапазона, если на поле даты существует индекс, поддерживающий функциональные ключи, хотя диапазон часто работает предсказуемее на разных СУБД.

Особенности работы с разными СУБД

Платформа 1С:Предприятие поддерживает работу с различными системами управления базами данных, такими как встроенный файловый сервер, Microsoft SQL Server, PostgreSQL и Oracle. Хотя синтаксис запросов 1С унифицирован, под капотом он транслируется в нативный SQL конкретной СУБД. В большинстве случаев разработчику не нужно беспокоиться о различиях, так как драйвер 1С берет это на себя. Однако существуют тонкие моменты, связанные с часовыми поясами и хранением времени.

В файловом варианте базы данных время хранится в локальном времени компьютера, на котором запущен сервер 1С или файл открыт локально. В клиент-серверном варианте (SQL) время часто хранится в формате UTC или с учетом настроек сервера БД. При записи жестких констант в запросе 1С интерпретирует их как локальное время пользователя или сервера приложений. Если ваш сервер 1С и сервер БД находятся в разных часовых поясах, могут возникнуть расхождения при выборке данных по точному времени.

Таблица ниже демонстрирует различия в поведении при работе с датами в зависимости от окружения:

Параметр Файловая база SQL Server / PostgreSQL Рекомендация
Хранение времени Локальное время ОС Часто UTC или локальное сервера БД Использовать диапазоны с запасом
Точность До секунды До миллисекунд (зависит от типа поля) Не использовать точное равенство
Скорость выборки Зависит от индексов файла Зависит от планов выполнения SQL Проверять планы запросов
Часовые пояса Не учитываются явно Могут сдвигать время при конвертации Сверять настройки сервера

Для минимизации проблем рекомендуется всегда использовать диапазоны дат с небольшим запасом, если точность до секунды не является критичной для бизнес-логики. Например, при поиске документов за час можно расширить диапазон на минуту в обе стороны, чтобы нивелировать возможные рассинхронизации часов или особенности округления времени в СУБД.

Проблема високосных секунд

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

Типичные ошибки и способы их решения

Одной из самых распространенных ошибок является использование неправильных кавычек. Разработчики, привыкшие к стандартному SQL, могут использовать двойные кавычки для дат, что в 1С недопустимо. Другая частая ошибка — попытка использовать разделители в литерале даты, например '2023-01-01'. Запросовик 1С выдаст ошибку «Неверный формат даты», так как он ожидает сплошную строку цифр внутри апострофов.

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

⚠️ Внимание: Никогда не копируйте символы кавычек из текстовых редакторов или браузеров. Используйте только стандартный одинарный апостроф (') на клавиатуре в раскладке English.

Если вы получаете ошибку «Поле не найдено» при использовании даты, проверьте, не назвали ли вы поле так же, как ключевое слово или тип. Хотя имена полей обычно экранируются, в сложных конструкциях с вложенными запросами могут возникать коллизии. В таких случаях помогает явное указание псевдонима таблицы или использование квадратных скобок для имен полей, хотя для дат это требуется редко.

💡

90% ошибок с датами в запросах 1С связаны с неправильным форматом строки (наличие разделителей) или использованием неверных символов кавычек.

Оптимизация запросов с фильтрами по дате

Фильтрация по дате является одним из самых эффективных способов ускорения работы запросов, при условии, что на поле даты установлен индекс. Правильно записанное условие диапазона позволяет механизму 1С и СУБД использовать этот индекс для быстрого отсечения ненужных записей. Если же условие записано некорректно (например, с применением функций к полю в левой части оператора сравнения), индекс может не сработать, что приведет к полному сканированию таблицы.

Избегайте конструкций вида ГОД(ДатаДокумента) = 2023 в условии ГДЕ. Такая запись вынуждает систему вычислять год для каждой строки таблицы, что убивает производительность на больших объемах данных. Вместо этого используйте диапазон: ДатаДокумента >= '20230101' И ДатаДокумента < '20260101'. Это позволяет СУБД сразу перейти к нужному участку индекса.

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

⚠️ Внимание: Избегайте применения функций к полям таблицы в левой части условия сравнения (например, НАЧАЛОДНЯ(Поле)), если это возможно. Это отключает использование индексов и резко замедляет выполнение запроса.

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

💡

При отладке медленных запросов включите «Технологический журнал» и проанализируйте раздел «SQL», чтобы увидеть, какие именно индексы используются при фильтрации по дате.

Можно ли использовать русские слова «Дата» в запросе без кавычек?

Нет, в языке запросов 1С литералы дат должны быть обязательно заключены в одинарные кавычки (апострофы). Написание даты без кавычек будет воспринято как имя поля или таблицы, что приведет к ошибке выполнения запроса.

Как записать дату, если день или месяц состоит из одной цифры?

В формате литерала даты 1С (ГГГГММДД) всегда используются две цифры для месяца и дня. Если месяц январь, нужно писать 01, а не 1. Например, 5 мая 2023 года записывается как '20230505'.

Что делать, если нужно выбрать документы «до конца вчерашнего дня»?

Используйте диапазон от начала позапрошлого дня до начала вчерашнего дня не подойдет. Правильно: от начала вчерашнего дня (ТекущаяДата - 1) до начала сегодняшнего дня (ТекущаяДата). В запросе это: ГДЕ Дата >= 'ГГГГММДД_вчера' И Дата < 'ГГГГММДД_сегодня'.

Почему запрос с датой работает в консоли, но выдает ошибку в коде?

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

Как учесть часовой пояс при записи даты в запросе?

Явно указать часовой пояс в литерале даты в запросе 1С нельзя. Дата всегда интерпретируется в контексте времени сервера 1С или локального времени. Для работы с UTC необходимо конвертировать дату в коде 1С перед передачей её в запрос параметром, используя функцию УниверсальнаяДата() или ручное смещение.