В процессе разработки на платформе 1С часто возникает задача преобразования даты, представленной в виде строки, в другой строковый формат. Например, это может потребоваться для формирования текста запроса, вывода в печатную форму или для обмена данными с другими системами. Рассмотрим на примере обсуждения с форума, как правильно выполнить такое преобразование, а также разберем связанные с этим нюансы и лучшие практики.
Исходная задача звучала так: есть дата в формате ддММгггг, и ее нужно перевести в формат ггггММдд ччммсс. Однако в ходе диалога выяснилось, что на самом деле исходные данные — это строка вида "31.08.2012 0:00:00", которую нужно подготовить для использования в запросе, ожидающем формат ДАТАВРЕМЯ(гггг, мм, дд).
Проанализируем шаги и методы, которые помогут решить эту и подобные задачи.
Это основной и самый надежный способ, когда у вас есть строка, содержащая дату в одном из стандартных форматов. Процесс состоит из двух шагов: сначала мы преобразуем строку в системный тип Дата, а затем форматируем полученную дату в нужный нам строковый вид.
Шаг 1: Преобразование строки в тип `Дата`
Для этого используется системная функция Дата(). Она принимает на вход строку и пытается распознать в ней дату, основываясь на региональных настройках компьютера, где выполняется код. Для строки вида "31.08.2012 0:00:00" этот метод отлично сработает в большинстве случаев.
Шаг 2: Форматирование даты в нужную строку
После того как мы получили переменную типа Дата, мы можем превратить ее в строку любого формата с помощью функции Формат(). Эта функция очень гибкая и позволяет настроить вывод даты и времени с высокой точностью.
Посмотрим на итоговый код:
// Исходные данные
ВашаПеременная = "31.08.2012 0:00:00";
// Сначала преобразуем строку в тип Дата
ПромежуточнаяДата = Дата(ВашаПеременная);
// Теперь форматируем полученную дату в целевой формат
ДатаВНужномФормате = Формат(ПромежуточнаяДата, "ДФ=""гггг.ММ.дд ЧЧ:мм:сс""");
// Результат: "2012.08.31 00:00:00"
Можно объединить эти два действия в одну строку для краткости:
ДатаВНужномФормате = Формат(Дата(ВашаПеременная), "ДФ=""гггг.ММ.дд ЧЧ:мм:сс""");
Здесь ДФ — это параметр, указывающий формат даты (Date Format). Сама форматная строка "гггг.ММ.дд ЧЧ:мм:сс" задает желаемый вид: год из 4 цифр, месяц и день из двух, а также часы, минуты и секунды.
В ходе обсуждения был выявлен критически важный момент, о который часто "спотыкаются" разработчики. Регистр символов, обозначающих часы, имеет значение:
чч (в нижнем регистре) — представляет час в 12-часовом формате (с AM/PM, которые в русскоязычной локали обычно не отображаются).ЧЧ (в верхнем регистре) — представляет час в 24-часовом формате.Если вы по ошибке используете чч для времени после полудня, вы получите неверный результат. Например, 16:00 (4 часа дня) будет преобразовано в 04:00. Это особенно опасно при передаче данных в другие системы, например, в SQL Server, который ожидает 24-часовой формат. Всегда используйте ЧЧ, если вам нужен 24-часовой формат времени.
Иногда дата приходит в виде строки без разделителей, например, "31082012". В таком случае функция Дата() может не справиться. Для таких ситуаций подходит метод ручного разбора строки с помощью функций Лев(), Сред() и Прав().
Рассмотрим пример для строки формата "ддммгггг":
ИсходнаяСтрока = "31082012";
// Выделяем компоненты даты
Год = Прав(ИсходнаяСтрока, 4); // "2012"
Месяц = Сред(ИсходнаяСтрока, 3, 2); // "08"
День = Лев(ИсходнаяСтрока, 2); // "31"
// Собираем строку в формате, понятном для функции Дата() (ггггММдд)
СтрокаДляПреобразования = Год + Месяц + День; // "20120831"
// Преобразуем в дату
РезультатДата = Дата(СтрокаДляПреобразования);
Этот код можно записать и в одну строку, как было предложено на форуме:
РезультатДата = Дата(Прав("31082012", 4) + Сред("31082012", 3, 2) + Лев("31082012", 2));
Этот метод надежен, но применим только для строго определенных форматов строк.
Иногда требуется вывести дату в более "человеческом" формате, например, "31 августа 2012 г.". Чтобы добавить в форматную строку статический текст, его нужно заключить в одинарные кавычки. Это говорит функции Формат(), что символы внутри кавычек не нужно интерпретировать как часть шаблона даты.
Пример:
МояДата = ТекущаяДата();
// Вывод даты с добавлением "г." в конце
Результат = Формат(МояДата, "ДФ='dd MMMM yyyy ""г.""'"); // Например, "05 мая 2024 г."
Обратите внимание, что стандартная функция Формат() не умеет склонять слова (например, "год", "года", "лет"). Для этого потребуется написать собственную небольшую функцию.
Самый важный аспект, который был затронут в теме, — это использование дат в запросах, текст которых формируется динамически. Очень распространено заблуждение, что если текст запроса собирается "на лету", то в него невозможно передать параметры, и приходится "вклеивать" значения прямо в строку.
Это неверно и опасно! Подстановка значений в текст запроса в виде строки — плохая практика по двум причинам:
Правильный и безопасный способ — всегда использовать параметры. Это работает и для динамически формируемых запросов.
Рассмотрим правильный пример:
ТекстЗапроса = "
|ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка,
| ПоступлениеТоваровУслуг.Номер,
| ПоступлениеТоваровУслуг.Дата
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ИСТИНА";
// Динамически добавляем условие по дате
Если ЗначениеЗаполнено(ДатаНачала) И ЗначениеЗаполнено(ДатаОкончания) Тогда
// В текст запроса добавляем ПАРАМЕТРЫ, а не значения!
ТекстЗапроса = ТекстЗапроса + " И ПоступлениеТоваровУслуг.Дата МЕЖДУ &НачПериода И &КонПериода";
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
// Устанавливаем значения для параметров, только если они были добавлены в текст
Если ЗначениеЗаполнено(ДатаНачала) И ЗначениеЗаполнено(ДатаОкончания) Тогда
// Передаем значения типа Дата, а не строки!
Запрос.УстановитьПараметр("НачПериода", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("КонПериода", КонецДня(ДатаОкончания));
КонецЕсли;
Результат = Запрос.Выполнить();
При таком подходе платформа 1С сама позаботится о корректной передаче значения типа Дата в СУБД. Это избавляет от всех проблем с форматированием строк и делает код чистым, читаемым и безопасным.