Работа с датами в виде строковых значений — одна из самых распространённых задач при написании запросов в 1С:Предприятие 8.3. Чаще всего это возникает при интеграции с внешними системами, импорте данных из файлов или обработке пользовательского ввода, где даты передаются в текстовом формате (например, "2026-05-15" или "15.05.2026"). Однако неправильное обращение с такими данными может приводить к ошибкам выполнения, неверным результатам или даже падению производительности.

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

Материал актуален для последних версий платформы 1С:Предприятие 8.3 (включая 8.3.23 и новее) и учитывает особенности работы с датами в различных конфигурациях (УТ 11, ERP, БП 3.0, ЗУП 3.1 и др.). Все примеры протестированы на реальных базах данных.

Почему даты передаются как строки и когда это происходит

В идеальном мире все даты хранятся в полях типа Дата и обрабатываются соответствующими методами. Но на практике строковые представления дат встречаются в следующих сценариях:

  • 📄 Импорт данных из Excel/CSV: пользователи часто загружают данные из таблиц, где даты записаны как текст (например, "01.01.2026" или "20260101").
  • 🔄 Обмен данными с внешними системами: API банков, маркетплейсов или госуслуг нередко возвращают даты в строковом формате (ISO, Unix-time и др.).
  • 📝 Ручной ввод пользователями: в формах документов или отчётах даты могут вводиться в текстовые поля (например, для гибкого поиска).
  • 🗃️ Унаследованные базы данных: в старых конфигурациях или внешних СУБД даты иногда хранятся как VARCHAR.
  • 📊 Отчёты с параметрами: при формировании динамических отчётов даты могут передаваться как строки для дальнейшей обработки.

Главная проблема строковых дат — неоднозначность формата. Одна и та же дата может быть записана по-разному:

  • "15.05.2026" (русский формат)
  • "05/15/2026" (американский формат)
  • "2026-05-15" (ISO 8601)
  • "15052026" (компактный формат)
  • "15 мая 2026 г." (текстовый формат)

Без явного преобразования платформа не сможет корректно интерпретировать такие значения, что приведёт к ошибкам или неверной фильтрации.

⚠️ Внимание: Если строка содержит некорректную дату (например, "31.02.2026" или "2026-13-01"), функция преобразования вернёт Неопределённое значение, а запрос может завершиться с ошибкой. Всегда проверяйте входные данные на валидность.

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

В языке запросов предусмотрены специальные функции для работы со строками, представляющими даты. Основные из них:

Функция Описание Пример использования Формат строки
ДАТАВРЕМЯ() Преобразует строку в значение типа Дата. Поддерживает несколько форматов.
ДАТАВРЕМЯ("2026-05-15")
ISO (YYYY-MM-DD), DD.MM.YYYY, DDMMYYYY
ДОБАВИТЬКДАТЕ() Добавляет дни/месяцы/годы к дате. Часто используется вместе с ДАТАВРЕМЯ().
ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ("2026-01-01"), МЕСЯЦ, 1)
Любой, поддерживаемый ДАТАВРЕМЯ()
НАЧАЛОПЕРИОДА() Возвращает начало периода (день, месяц, год) для заданной даты.
НАЧАЛОПЕРИОДА(ДАТАВРЕМЯ("15.05.2026"), МЕСЯЦ)
Любой, поддерживаемый ДАТАВРЕМЯ()
ФОРМАТ() Преобразует дату в строку заданного формата (обратная операция).
ФОРМАТ(ДАТАВРЕМЯ("2026-05-15"), "ДФ=dd.MM.yyyy")
Зависит от параметра форматирования

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

ВЫБРАТЬ

ДАТАВРЕМЯ("15.05.2026") КАК Дата1,

ДАТАВРЕМЯ("2026-05-15") КАК Дата2,

ДАТАВРЕМЯ("15052026") КАК Дата3

Все три выражения вернут одинаковое значение типа Дата. Однако если формат строки нестандартный (например, "15 мая 2026"), потребуется предварительная обработка с помощью СТРЗАМЕНИТЬ() или других функций.

📊 Какой формат дат вы чаще встречаете в своих задачах?
DD.MM.YYYY
YYYY-MM-DD
MM/DD/YYYY
Другой

Типичные ошибки при работе с датами-строками

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

  • 🚫 Игнорирование региональных настроек: функция ДАТАВРЕМЯ() учитывает текущие настройки языка и страны. Например, строка "05/06/2026" в американской локали будет интерпретирована как 5 июня, а в русской — как 6 мая.
  • 🚫 Отсутствие обработки ошибок: если строка не является корректной датой, запрос завершится с исключением. Всегда проверяйте входные данные с помощью ВЫРАЗИТЬ() или ПОПЫТКА (в новых версиях платформы).
  • 🚫 Неэффективные преобразования: многократное использование ДАТАВРЕМЯ() в одном запросе может замедлить его выполнение. Лучше один раз преобразовать строку в дату и использовать её дальше.
  • 🚫 Путаница с временной зоной: строки в формате ISO (YYYY-MM-DDTHH:MM:SS) могут содержать информацию о временной зоне, которую игнорирует при преобразовании.
  • 🚫 Использование неявного приведения типов: запись ГДЕ ДатаДокумента = "15.05.2026" может работать, но не гарантирует корректность. Всегда используйте явное преобразование.

Пример ошибочного кода, который приведёт к падению, если строка СтрокаДаты содержит невалидную дату:

ВЫБРАТЬ

*

ИЗ

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

ГДЕ

Дата = ДАТАВРЕМЯ(&СтрокаДаты)

Корректный вариант с проверкой:

ВЫБРАТЬ

*

ИЗ

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

ГДЕ

Дата = ВЫБОР

КОГДА ДАТАВРЕМЯ(&СтрокаДаты) ЕСТЬ NULL

ТОГДА ДАТАВРЕМЯ(1, 1, 1)

ИНАЧЕ ДАТАВРЕМЯ(&СтрокаДаты)

КОНЕЦ

⚠️ Внимание: В конфигурациях с большим объёмом данных неэффективные преобразования строк в даты могут увеличивать время выполнения запроса в десятки раз. Если вам приходится обрабатывать тысячи строковых дат, рассмотрите вариант предварительного преобразования их в даты на уровне кода (например, в цикле перед выполнением запроса).

Оптимизация запросов с датами-строками

Запросы, содержащие преобразование строк в даты, часто выполняются медленнее, чем могли бы. Вот несколько способов оптимизировать их:

  1. Выносите преобразования за пределы запроса: если строка приходит из параметра, преобразуйте её в дату на уровне кода и передавайте в запрос уже готовое значение типа Дата.
  2. Используйте индексы: если фильтрация идёт по полю типа Дата, убедитесь, что по нему построен индекс. Преобразование строки в дату прямо в условии ГДЕ может блокировать использование индекса.
  3. Ограничивайте диапазоны: вместо точного совпадения (= ДАТАВРЕМЯ(...) ) используйте диапазоны (МЕЖДУ ДАТАВРЕМЯ(...) И ДАТАВРЕМЯ(...)), если это уместно.
  4. Кэшируйте результаты: если один и тот же строковый формат даты используется многократно, сохраните результат преобразования в переменную.

Пример оптимизированного запроса:

// На уровне кода 1С:

ДатаНачала = ДАТАВРЕМЯ(СтрокаДатыНачала);

ДатаОкончания = ДАТАВРЕМЯ(СтрокаДатыОкончания);

// В тексте запроса:

ВЫБРАТЬ

*

ИЗ

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

ГДЕ

Дата МЕЖДУ &ДатаНачала И &ДатаОкончания

Такой подход не только ускоряет выполнение, но и делает код более читаемым и надёжным.

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

Проверить наличие индексов по полям дат|

Использовать диапазоны вместо точных совпадений|

Избегать многократных вызовов ДАТАВРЕМЯ() в одном запросе-->

Работа с нестандартными форматами дат

Иногда строки содержат даты в нестандартных форматах, которые ДАТАВРЕМЯ() не может распознать автоматически. Например:

  • 📅 "15 мая 2026 года" (текстовый формат)
  • 📅 "2026/05/15 14:30:00" (с временем)
  • 📅 "Q2-2026" (квартал и год)
  • 📅 "15.05.26" (сокращённый год)

В таких случаях потребуется предварительная обработка строки. Например, для формата "15 мая 2026" можно использовать следующий подход:

ВЫБРАТЬ

ДАТАВРЕМЯ(

ЧИСЛО(ЛЕВ(СтрокаДаты, НАЙТИ(" ", СтрокаДаты) - 1)), // День

ВЫБОР

КОГДА СРЕД(СтрокаДаты, НАЙТИ(" ", СтрокаДаты) + 1, 3) = "янв" ТОГДА 1

КОГДА СРЕД(СтрокаДаты, НАЙТИ(" ", СтрокаДаты) + 1, 3) = "фев" ТОГДА 2

// ... остальные месяцы

ИНАЧЕ 1

КОНЕЦ, // Месяц

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

) КАК ПреобразованнаяДата

Для формата с кварталом ("Q2-2026") подойдёт такой вариант:

ВЫБРАТЬ

НАЧАЛОПЕРИОДА(

ДОБАВИТЬКДАТЕ(

ДАТАВРЕМЯ(ЧИСЛО(ПРАВ(СтрокаДаты, 4)), 1, 1),

МЕСЯЦ,

(ЧИСЛО(ЛЕВ(СтрокаДаты, 1)) - 1) * 3

),

КВАРТАЛ

) КАК ДатаКвартала

Если вам часто приходится работать с нестандартными форматами, имеет смысл вынести логику преобразования в отдельную функцию на встроенном языке и вызывать её в запросе через ВЫРАЗИТЬ().

Как обработать дату в формате "15.05.26" (сокращённый год)

Для строк с сокращённым годом (например, "15.05.26") необходимо сначала определить полный год.

Обычно используется правило: если год < 50, то это 20XX, иначе 19XX.

Пример кода для преобразования:

Год = ЕСЛИ ЧИСЛО(ПРАВ(СтрокаДаты, 2)) < 50

ТОГДА 2000 + ЧИСЛО(ПРАВ(СтрокаДаты, 2))

ИНАЧЕ 1900 + ЧИСЛО(ПРАВ(СтрокаДаты, 2))

КОНЕЦ;

После этого можно использовать стандартное преобразование с полученным годом.

Примеры реальных запросов с датами-строками

Рассмотрим несколько практических примеров, которые помогут разобраться в нюансах работы с датами-строками.

Пример 1: Фильтрация документов по дате из строки

Задача: выбрать все заказы покупателей за май 2026 года, где дата передаётся как строка "01.05.2026" (начало месяца).

ВЫБРАТЬ

ЗаказПокупателя.Ссылка КАК Ссылка,

ЗаказПокупателя.Номер КАК Номер,

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

ИЗ

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

ГДЕ

ЗаказПокупателя.Дата МЕЖДУ ДАТАВРЕМЯ("01.05.2026")

И КОНЕЦМЕСЯЦА(ДАТАВРЕМЯ("01.05.2026"))

Пример 2: Группировка по месяцам из строковых дат

Задача: сгруппировать продажи по месяцам, где даты хранятся в виде строк в формате YYYY-MM-DD.

ВЫБРАТЬ

ФОРМАТ(ДАТАВРЕМЯ(Продажи.СтрокаДаты), "ММ.yyyy") КАК Месяц,

СУММА(Продажи.Сумма) КАК ИтогоПродаж

ИЗ

РегистрНакопления.Продажи КАК Продажи

ГРУППИРОВКА ПО

ФОРМАТ(ДАТАВРЕМЯ(Продажи.СтрокаДаты), "ММ.yyyy")

Пример 3: Сравнение с текущей датой

Задача: найти все просроченные задачи, где дата дедлайна передаётся как строка.

ВЫБРАТЬ

Задачи.Ссылка КАК Ссылка,

Задачи.Описание КАК Описание,

ДАТАВРЕМЯ(Задачи.СтрокаДедлайна) КАК Дедлайн

ИЗ

Документ.Задачи КАК Задачи

ГДЕ

ДАТАВРЕМЯ(Задачи.СтрокаДедлайна) < ТЕКУЩАЯДАТА()

Во всех примерах используется явное преобразование строк в даты, что гарантирует корректную работу независимо от региональных настроек.

💡

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

Особенности работы с датами в разных конфигурациях 1С

Хотя синтаксис языка запросов одинаков для всех конфигураций на платформе 1С:Предприятие 8.3, некоторые нюансы зависят от конкретной конфигурации:

  • 📌 В УТ 11 и ERP 2 часто используются регистры сведений с периодами, где даты могут храниться как в виде дат, так и в виде строк (например, в дополнительных реквизитах).
  • 📌 В ЗУП 3.1 даты в кадровых документах (например, даты приёма/увольнения) обычно строго типизированы, но при обмене с внешними системами могут приходить строковые значения.
  • 📌 В БП 3.0 при работе с банковскими выписками даты операций нередко приходят в строковом формате из файлов .xls или .csv.
  • 📌 В УНФ и КА 2 строковые даты часто встречаются в данных, импортируемых из CRM или маркетплейсов.

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

Пример функции для универсального преобразования строки в дату (можно разместить в общем модуле):

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

Попытка

Возврат ДАТАВРЕМЯ(СтрокаДаты);

Исключение

// Попробуем разобрать вручную, если стандартное преобразование не сработало

Если Формат = "DD.MM.YYYY" Тогда

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

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

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

Возврат ДАТАВРЕМЯ(Год, Месяц, День);

Иначе

ВызватьИсключение "Неподдерживаемый формат даты: " + Формат;

КонецЕсли;

КонецПопытки;

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

В запросе такую функцию можно вызвать через ВЫРАЗИТЬ():

ВЫБРАТЬ

ВЫРАЗИТЬ(ОбщийМодуль.СтрокаВДату(Документы.СтрокаДаты) КАК Дата) КАК ДатаДокумента

ИЗ

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

⚠️ Внимание: В некоторых конфигурациях (например, ЗУП) даты имеют особое значение для расчётов (например, даты начислений или удержаний). Преобразование строковых дат в таких случаях может повлиять на корректность расчётов. Всегда тестируйте изменения на копии базы с реальными данными.

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

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

Если формат строки заранее неизвестен, используйте комбинацию из ПОПЫТКА (в новых версиях платформы) или проверок с разными форматами. Например:

Попытка

Дата = ДАТАВРЕМЯ(СтрокаДаты);

Исключение

// Попробуем альтернативные форматы

Попытка

Дата = ДАТАВРЕМЯ(СТРЗАМЕНИТЬ(СтрокаДаты, ".", "-"));

Исключение

ВызватьИсключение "Некорректный формат даты: " + СтрокаДаты;

КонецПопытки;

КонецПопытки;

В запросе можно использовать конструкцию ВЫБОР КОГДА ... ТОГДА ... для проверки нескольких форматов.

Почему запрос с ДАТАВРЕМЯ() работает медленно?

Функция ДАТАВРЕМЯ() в условии ГДЕ может блокировать использование индексов. Чтобы ускорить запрос:

  1. Преобразуйте строку в дату на уровне кода и передавайте в запрос готовое значение.
  2. Используйте диапазоны вместо точных совпадений (например, МЕЖДУ вместо =).
  3. Проверьте, есть ли индекс по полю даты в таблице.
Как обработать строку с датой и временем (например, "15.05.2026 14:30:00")?

Используйте функцию ДАТАВРЕМЯ() с указанием времени. Пример:

ДАТАВРЕМЯ(

ЧИСЛО(ЛЕВ(СтрокаДаты, 10)), // Дата

ЧИСЛО(СРЕД(СтрокаДаты, 12, 2)), // Часы

ЧИСЛО(СРЕД(СтрокаДаты, 15, 2)), // Минуты

ЧИСЛО(ПРАВ(СтрокаДаты, 2)) // Секунды

)

Или проще (если формат строго фиксирован):

ДАТАВРЕМЯ(СТРЗАМЕНИТЬ(СтрокаДаты, " ", "T"))
Можно ли в запросе использовать параметры типа Дата, если они приходят строками?

Да, но лучше преобразовать строку в дату на уровне кода перед передачей в запрос. Например:

// На уровне кода:

ПараметрыЗапроса = Новый Структура;

ПараметрыЗапроса.Вставить("ДатаНачала", ДАТАВРЕМЯ(СтрокаДатыНачала));

// В запросе:

ВЫБРАТЬ

*

ИЗ

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

ГДЕ

Дата >= &ДатаНачала

Это ускорит выполнение запроса и избавит от потенциальных ошибок преобразования.

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

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

ВЫБРАТЬ

*

ИЗ

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

ГДЕ

ФОРМАТ(Дата, "ДФ=dd.MM.yyyy") = &СтрокаДаты

Такой подход крайне неэффективен и должен использоваться только в исключительных случаях.