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

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

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

Базовый синтаксис форматирования даты в запросах 1С

В языке запросов 1С:Предприятие 8 для преобразования даты в строку используется функция ФОРМАТ(). Она принимает два обязательных параметра: саму дату и строку формата. Например, чтобы получить дату в виде "31.12.2023", используйте:

ВЫБРАТЬ

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

ИЗ

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

Где ДФ — это указатель на формат даты (Date Format), а dd.MM.yyyy — шаблон вывода. Основные элементы шаблона:

  • 📅 dd — день месяца (01–31)
  • 📅 MM — месяц (01–12)
  • 📅 yyyy — год (четырёхзначный)
  • 🕒 HH:mm:ss — время (часы, минуты, секунды)

Это значит, что отформатированное значение нельзя использовать в арифметических операциях или сравнениях без обратного преобразования. Например, такой запрос вернёт ошибку:

ВЫБРАТЬ

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

// ОШИБКА: нельзя сравнивать строки с датами!

💡

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

Популярные форматы даты и их применение

Выбор формата даты зависит от задачи. Например, для отчётов чаще всего используют "dd.MM.yyyy", а для логов или технических журналов — "yyyy-MM-dd HH:mm:ss". Рассмотрим наиболее востребованные варианты:

Формат Пример вывода Типичное применение
"ДФ=dd.MM.yyyy" 15.05.2023 Отчёты для пользователей, документы
"ДФ=dd MMMM yyyy" 15 мая 2023 Официальные письма, презентации
"ДФ=yyyy-MM-dd" 2023-05-15 Обмен данными, API, SQL-запросы
"ДФ=dd.MM.yyyy HH:mm" 15.05.2023 14:30 Журналы событий, логи

Для работы с временем используйте комбинацию формата даты и времени. Например, чтобы вывести дату и время создания документа в формате "15.05.2023 14:30:45", применяйте:

ВЫБРАТЬ

ФОРМАТ(ДатаДокумента, "ДФ=dd.MM.yyyy; ВФ=HH:mm:ss") КАК ПолнаяДата

Здесь ВФ — это указатель на формат времени (Время Формат). Разделитель между датой и временем зависит от локализации системы. В российской версии по умолчанию используется пробел.

📊 Какой формат даты вы используете чаще всего?
dd.MM.yyyy
yyyy-MM-dd
dd MMMM yyyy
Другой

Работа с локализацией и региональными настройками

Формат даты может различаться в зависимости от региональных настроек 1С:Предприятие. Например, в американской локализации по умолчанию используется формат MM/dd/yyyy, а в европейской — dd.MM.yyyy. Чтобы избежать путаницы, всегда явно указывайте формат в функции ФОРМАТ().

Если вам нужно получить дату в формате текущей локализации без явного указания шаблона, используйте функцию СТРОКА():

ВЫБРАТЬ

СТРОКА(ДатаДокумента) КАК ЛокализованнаяДата

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

Как узнать текущую локализацию в 1С?

Чтобы проверить текущие региональные настройки, выполните в отладчике:

Сообщить(НСтр("ru = 'Русский'; en = 'Английский'"));

или посмотрите значение системного параметра ТекущаяДатаСеанса() — его формат отражает настройки пользователя.

Для принудительного использования конкретной локализации независимо от настроек пользователя укажите её в параметрах формата. Например, для американского формата:

ВЫБРАТЬ

ФОРМАТ(ДатаДокумента, "ДФ=MM/dd/yyyy; Л=EN") КАК АмериканскийФормат

Где Л=EN — это указатель локализации (Локаль). Поддерживаются следующие значения:

  • 🌍 RU — русский
  • 🌍 EN — английский
  • 🌍 DE — немецкий
  • 🌍 FR — французский
💡

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

Динамическое форматирование в зависимости от условий

Иногда требуется изменять формат даты в зависимости от каких-либо условий. Например, для документов старше года выводить только год, а для свежих — полную дату. Это можно реализовать с помощью конструкции ВЫБОР КОГДА:

ВЫБРАТЬ

ВЫБОР

КОГДА ДатаДокумента < ДАТАВРЕМЯ(1, 1, ГОД(ТекущаяДата()) - 1)

ТОГДА ФОРМАТ(ДатаДокумента, "ДФ=yyyy")

ИНАЧЕ ФОРМАТ(ДатаДокумента, "ДФ=dd.MM.yyyy")

КОНЕЦ КАК ГибкаяДата

В этом примере:

  • 📅 ДАТАВРЕМЯ(1, 1, ГОД(ТекущаяДата()) - 1) — это 1 января прошлого года.
  • 📌 ВЫБОР КОГДА проверяет, относится ли дата документа к прошлым годам.
  • 📝 Для старых документов выводится только год, для новых — полная дата.

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

ВЫБРАТЬ

ВЫБОР

КОГДА ВидДокумента = ЗНАЧЕНИЕ(Справочник.ВидыДокументов.Отгрузка)

ТОГДА ФОРМАТ(ДатаДокумента, "ДФ=dd.MM.yyyy; ВФ=HH:mm")

ИНАЧЕ ФОРМАТ(ДатаДокумента, "ДФ=dd.MM.yyyy")

КОНЕЦ КАК ДатаСУчетомВида

Убедитесь, что все условия в ВЫБОР КОГДА покрывают возможные сценарии|

Протестируйте запрос на граничных значениях (например, даты ровно год назад)|

Проверьте производительность при большом объёме данных|

Документируйте логику форматирования для других разработчиков

-->

Ошибки при форматировании дат и как их избежать

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

⚠️ Внимание: Если в запросе используется функция ФОРМАТ() с неверным шаблоном (например, "ДФ=MM-dd-yyyy" вместо "ДФ=dd.MM.yyyy"), система не вернёт ошибку, но даты будут отформатированы некорректно. Всегда проверяйте вывод на тестовых данных.

Типичные ошибки:

  1. Путаница между MM и mm: MM — это месяц, а mm — минуты. Использование "ДФ=dd.mm.yyyy" приведёт к выводу даты в виде 15.05.2023 (где 05 — это минуты, а не месяц!).
  2. Неучёт локализации: Если не указать явный формат, результат ФОРМАТ() может отличаться на разных клиентских машинах.
  3. Сравнение строк вместо дат: Как упоминалось ранее, отформатированная дата — это строка. Сравнивать её с другой строкой ("15.05.2023" > "01.01.2023") некорректно с точки зрения логики (сравниваются символы, а не даты).

Чтобы избежать ошибок, следуйте правилам:

  • 🔍 Всегда проверяйте шаблон формата на тестовых данных.
  • 📋 Для сравнений используйте исходные поля даты, а не строки.
  • 🌐 Явно указывайте локализацию, если формат критичен для бизнес-логики.

Особенно опасна ошибка с MM и mm в системах, где даты используются для расчётов (например, в бухгалтерских отчётах). Неправильное форматирование может привести к искажению финансовых данных.

Продвинутые техники: работа с временными зонами и смещениями

В распределённых системах или при интеграции с внешними сервисами может потребоваться учитывать временные зоны. В 1С:Предприятие для этого используются функции ДОБАВИТЬКДАТЕ() и НАЧАЛОДНЯ() в комбинации с учётными записями.

Например, чтобы привести дату к московскому времени (UTC+3), используйте:

ВЫБРАТЬ

ДОБАВИТЬКДАТЕ(ДатаДокумента, СЕКУНДА, 3 * 3600) КАК ДатаПоМск

Где 3 * 3600 — это смещение в секундах (3 часа × 3600 секунд). Для обратного преобразования (из московского времени в UTC):

ВЫБРАТЬ

ДОБАВИТЬКДАТЕ(ДатаДокумента, СЕКУНДА, -3 * 3600) КАК ДатаВUTC

Для работы с началом или концом дня (что актуально для отчётов по календарным периодам) используйте:

ВЫБРАТЬ

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

КОНЕЦДНЯ(ДатаДокумента) КАК КонецДня

Это полезно, например, для фильтрации документов за конкретный день без учёта времени:

ВЫБРАТЬ

*

ИЗ

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

ГДЕ

ДатаДокумента >= НАЧАЛОДНЯ(&ПараметрДата)

И ДатаДокумента <= КОНЕЦДНЯ(&ПараметрДата)

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

Оптимизация запросов с датами для крупных баз

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

  1. Избегайте форматирования в ГДЕ: Не пишите условий вроде ГДЕ ФОРМАТ(Дата, "ДФ=dd.MM.yyyy") = "15.05.2023". Вместо этого фильтруйте по исходному полю:
    ГДЕ Дата = ДАТАВРЕМЯ(15, 5, 2023)
  2. Используйте индексы: Убедитесь, что поля даты проиндексированы в метаданных. Для этого откройте конфигуратор и проверьте свойства соответствующих реквизитов.
  3. Ограничивайте период: Если запрос анализирует данные за длительный срок, разбивайте его на более короткие интервалы (например, помесячно).

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

ВЫБРАТЬ

*

ИЗ

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

ГДЕ

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

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

Для ещё большей производительности можно использовать временные таблицы:

ДатаНачала = НАЧАЛОМЕСЯЦА(ТЕКУЩАЯДАТА());

ДатаОкончания = КОНЕЦМЕСЯЦА(ТЕКУЩАЯДАТА());

ВЫБРАТЬ

*

ИЗ

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

ГДЕ

Док.ДатаДокумента МЕЖДУ ДатаНачала И ДатаОкончания

Это уменьшает нагрузку на сервер, так как условия вычисляются один раз, а не для каждой строки.

FAQ: Частые вопросы по форматированию дат в 1С

Как вывести название месяца прописью (например, "май" вместо "05")?

Используйте формат с четырьмя буквами MMMM:

ФОРМАТ(ДатаДокумента, "ДФ=dd MMMM yyyy")

Это вернёт строку вида "15 мая 2023". Для сокращённого названия (например, "май") используйте MMM.

Можно ли в одном запросе вывести дату в разных форматах?

Да, просто добавьте несколько колонок с разными шаблонами:

ВЫБРАТЬ

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

ФОРМАТ(ДатаДокумента, "ДФ=dd MMMM yyyy") КАК ПолныйФормат

Как отформатировать дату без разделителей (например, "15052023")?

Уберите разделители из шаблона:

ФОРМАТ(ДатаДокумента, "ДФ=ddMMyyyy")

Это часто требуется для генерации имён файлов или идентификаторов.

Почему функция ФОРМАТ() возвращает пустую строку?

Это происходит, если на вход передано значение NULL или некорректная дата. Проверьте исходные данные с помощью функции ЕСТЬNULL():

ВЫБРАТЬ

ЕСТЬNULL(ФОРМАТ(ДатаДокумента, "ДФ=dd.MM.yyyy"), "Нет даты") КАК БезопаснаяДата

Как вывести дату в формате ISO 8601 (например, "2023-05-15T14:30:00")?

Используйте комбинацию формата даты и времени с буквой T в шаблоне:

ФОРМАТ(ДатаДокумента, "ДФ=yyyy-MM-dd; ВФ=HH:mm:ss; Р='T'")

Параметр Р (Разделитель) позволяет вставить произвольный символ между датой и временем.