При работе с датами в 1С разработчики часто сталкиваются с неожиданным поведением стандартной функции Формат(). Классический пример: при попытке получить дату в виде "ДД.ММ.ГГГГ" для числа меньше десятого, например, 9 апреля, система выводит строку с лишним пробелом в начале — " 9.04.2014" вместо ожидаемого "09.04.2014".
В этой статье мы подробно разберем, почему так происходит, и рассмотрим несколько способов решения этой задачи, от простых обходных путей до наиболее правильного и рекомендованного метода.
На первый взгляд, такое поведение может показаться ошибкой платформы, но на самом деле это ее штатная функциональность, связанная с региональными настройками. Проанализируем причину подробнее.
Когда мы используем конструкцию:
МояДата = '20140409';
СтрокаДаты = Формат(МояДата, "ДФ=dd.MM.yyyy"); // Результат: " 9.04.2014"
Параметр ДФ (сокращение от "ДатаФормат") указывает платформе 1С, что дату нужно форматировать в соответствии с локальными настройками операционной системы или настройками информационной базы. Во многих русскоязычных локалях (региональных стандартах) принято выравнивать даты в отчетах и списках. Для этого дни, состоящие из одной цифры (с 1 по 9), дополняются слева незначащим пробелом, а не нулем.
Интересно, что если убрать разделители, то проблема исчезает:
СтрокаДатыБезРазделителей = Формат(МояДата, "ДФ=ddMMyyyy"); // Результат: "09042014"
Это подтверждает, что пробел добавляется именно как часть форматирования по локальным правилам при наличии разделителей. Теперь, когда мы выяснили причину, рассмотрим, как получить желаемый результат.
Самый простой и быстрый способ, который приходит на ум — это просто убрать нежелательный пробел с помощью строковой функции. Для этого отлично подходит функция СтрЗаменить().
Посмотрим на пример:
ИсходнаяДата = ТекущаяДата();
// Сначала получаем строку с пробелом
НеправильнаяСтрока = Формат(ИсходнаяДата, "ДФ=dd.MM.yyyy");
// Затем заменяем пробел на ноль
ПравильнаяСтрока = СтрЗаменить(НеправильнаяСтрока, " ", "0");
// Если день в дате двузначный (например, 10-е число),
// то пробела не будет, и замена не произойдет.
Плюсы этого метода:
Минусы:
Этот метод предполагает получение каждой части даты (день, месяц, год) отдельно, форматирование каждой части с нужными параметрами и последующее объединение (конкатенацию) в единую строку.
Разберем по шагам:
День() и форматируем его как число с ведущим нулем.Месяц()).Год()).Пример кода:
ИсходнаяДата = ТекущаяДата();
// Форматируем день: ЧЦ=2 (число цифр 2), ЧВН= (выводить ведущие нули), ЧГ=0 (без группировки разрядов)
СтрокаДня = Формат(День(ИсходнаяДата), "ЧЦ=2; ЧВН=; ЧГ=0");
// Форматируем месяц по тому же принципу
СтрокаМесяца = Формат(Месяц(ИсходнаяДата), "ЧЦ=2; ЧВН=; ЧГ=0");
// Форматируем год
СтрокаГода = Формат(Год(ИсходнаяДата), "ЧЦ=4; ЧВН=; ЧГ=0");
// Собираем итоговую строку
Результат = СтрокаДня + "." + СтрокаМесяца + "." + СтрокаГода; // Результат: "09.04.2014"
Плюсы этого метода:
Минусы:
Это самый элегантный, правильный и эффективный способ решения проблемы. Он заключается в небольшом изменении самой форматной строки, передаваемой в функцию Формат().
Чтобы заставить платформу 1С игнорировать региональные настройки и строго следовать заданному шаблону, его необходимо заключить в одинарные кавычки.
Посмотрим на правильный синтаксис:
ИсходнаяДата = ТекущаяДата();
Результат = Формат(ИсходнаяДата, "ДФ='dd.MM.yyyy'"); // Результат: "09.04.2014"
Как это работает? Одинарные кавычки внутри параметра ДФ говорят функции Формат(): "Не используй системные представления даты. Вместо этого, используй строку 'dd.MM.yyyy' как буквальный шаблон". При этом зарезервированные последовательности символов, такие как dd (день с ведущим нулем), MM (месяц с ведущим нулем) и yyyy (год из четырех цифр), по-прежнему распознаются и заменяются соответствующими значениями даты. А вот разделители и общая структура воспринимаются буквально, без добавления локальных "улучшений" вроде пробела.
Плюсы этого метода:
Таким образом, мы видим, что кажущаяся странной проблема имеет логичное объяснение и элегантное решение. Использование формата ДФ='dd.MM.yyyy' является лучшей практикой для получения предсказуемого и независимого от настроек окружения результата при форматировании дат в 1С.