Работа с датами в запросах 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") КАК ПолнаяДата
Здесь ВФ — это указатель на формат времени (Время Формат). Разделитель между датой и временем зависит от локализации системы. В российской версии по умолчанию используется пробел.
Работа с локализацией и региональными настройками
Формат даты может различаться в зависимости от региональных настроек 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")
КОНЕЦ КАК ДатаСУчетомВида
Убедитесь, что все условия в ВЫБОР КОГДА покрывают возможные сценарии|
Протестируйте запрос на граничных значениях (например, даты ровно год назад)|
Проверьте производительность при большом объёме данных|
Документируйте логику форматирования для других разработчиков
-->
Ошибки при форматировании дат и как их избежать
Даже опытные программисты 1С иногда допускают ошибки при работе с датами. Рассмотрим наиболее распространённые проблемы и способы их решения.
⚠️ Внимание: Если в запросе используется функцияФОРМАТ()с неверным шаблоном (например,"ДФ=MM-dd-yyyy"вместо"ДФ=dd.MM.yyyy"), система не вернёт ошибку, но даты будут отформатированы некорректно. Всегда проверяйте вывод на тестовых данных.
Типичные ошибки:
- Путаница между
MMиmm:MM— это месяц, аmm— минуты. Использование"ДФ=dd.mm.yyyy"приведёт к выводу даты в виде15.05.2023(где05— это минуты, а не месяц!). - Неучёт локализации: Если не указать явный формат, результат
ФОРМАТ()может отличаться на разных клиентских машинах. - Сравнение строк вместо дат: Как упоминалось ранее, отформатированная дата — это строка. Сравнивать её с другой строкой (
"15.05.2023" > "01.01.2023") некорректно с точки зрения логики (сравниваются символы, а не даты).
Чтобы избежать ошибок, следуйте правилам:
- 🔍 Всегда проверяйте шаблон формата на тестовых данных.
- 📋 Для сравнений используйте исходные поля даты, а не строки.
- 🌐 Явно указывайте локализацию, если формат критичен для бизнес-логики.
Особенно опасна ошибка с MM и mm в системах, где даты используются для расчётов (например, в бухгалтерских отчётах). Неправильное форматирование может привести к искажению финансовых данных.
Продвинутые техники: работа с временными зонами и смещениями
В распределённых системах или при интеграции с внешними сервисами может потребоваться учитывать временные зоны. В 1С:Предприятие для этого используются функции ДОБАВИТЬКДАТЕ() и НАЧАЛОДНЯ() в комбинации с учётными записями.
Например, чтобы привести дату к московскому времени (UTC+3), используйте:
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(ДатаДокумента, СЕКУНДА, 3 * 3600) КАК ДатаПоМск
Где 3 * 3600 — это смещение в секундах (3 часа × 3600 секунд). Для обратного преобразования (из московского времени в UTC):
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(ДатаДокумента, СЕКУНДА, -3 * 3600) КАК ДатаВUTC
Для работы с началом или концом дня (что актуально для отчётов по календарным периодам) используйте:
ВЫБРАТЬ
НАЧАЛОДНЯ(ДатаДокумента) КАК НачалоДня,
КОНЕЦДНЯ(ДатаДокумента) КАК КонецДня
Это полезно, например, для фильтрации документов за конкретный день без учёта времени:
ВЫБРАТЬ
*
ИЗ
Документ.ЗаказПокупателя
ГДЕ
ДатаДокумента >= НАЧАЛОДНЯ(&ПараметрДата)
И ДатаДокумента <= КОНЕЦДНЯ(&ПараметрДата)
⚠️ Внимание: При работе с временными зонами учитывайте, что функция ТЕКУЩАЯДАТА() возвращает дату и время сервера, а не клиента. Если пользователи работают из разных регионов, это может привести к расхождениям в отчётах.
Оптимизация запросов с датами для крупных баз
В больших базах данных запросы с датами могут выполняться медленно, особенно если используются функции форматирования или сложные условия. Чтобы ускорить работу:
- Избегайте форматирования в
ГДЕ: Не пишите условий вродеГДЕ ФОРМАТ(Дата, "ДФ=dd.MM.yyyy") = "15.05.2023". Вместо этого фильтруйте по исходному полю:ГДЕ Дата = ДАТАВРЕМЯ(15, 5, 2023) - Используйте индексы: Убедитесь, что поля даты проиндексированы в метаданных. Для этого откройте конфигуратор и проверьте свойства соответствующих реквизитов.
- Ограничивайте период: Если запрос анализирует данные за длительный срок, разбивайте его на более короткие интервалы (например, помесячно).
Пример оптимизированного запроса для выборки документов за текущий месяц:
ВЫБРАТЬ
*
ИЗ
Документ.ПоступлениеТоваров
ГДЕ
ДатаДокумента >= НАЧАЛОМЕСЯЦА(ТЕКУЩАЯДАТА())
И ДатаДокумента <= КОНЕЦМЕСЯЦА(ТЕКУЩАЯДАТА())
Для ещё большей производительности можно использовать временные таблицы:
ДатаНачала = НАЧАЛОМЕСЯЦА(ТЕКУЩАЯДАТА());
ДатаОкончания = КОНЕЦМЕСЯЦА(ТЕКУЩАЯДАТА());
ВЫБРАТЬ
*
ИЗ
Документ.ПоступлениеТоваров КАК Док
ГДЕ
Док.ДатаДокумента МЕЖДУ ДатаНачала И ДатаОкончания
Это уменьшает нагрузку на сервер, так как условия вычисляются один раз, а не для каждой строки.
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'")
Параметр Р (Разделитель) позволяет вставить произвольный символ между датой и временем.