При выводе дат с помощью функции Формат разработчики часто сталкиваются с неожиданным поведением. Например, при использовании локального формата длинной даты ДЛФ=DD код возвращает строку вида «24 апреля 2017 г.». Однако при детальном анализе строки в текстовых редакторах или при передаче данных во внешние системы выясняется, что между цифрой года и сокращением «г.» находится не стандартный пробел, а специальный непечатаемый символ. Разберем, почему так происходит, какие скрытые проблемы это влечет за собой и как корректно управлять пробелами при форматировании.
Выясним причину такого поведения платформы. При использовании параметра ДЛФ (локальный формат даты) платформа 1С строго ориентируется на региональные стандарты отображения информации. В русской типографике действует жесткое правило: сокращения «г.» или «года» не должны отрываться от числа года и переноситься на новую строку.
Для соблюдения этого правила платформа автоматически подставляет между годом и буквой «г.» специальный неразрывный пробел — Символы.НПП (символ с кодом 160 в таблице Unicode U+00A0), а не обычный клавиатурный пробел с кодом 32.
Аналогичная логика применяется платформой и при форматировании чисел: по умолчанию разделителем групп триад (параметр ЧРГ) в русской локализации также выступает неразрывный пробел, чтобы разряды числа не переносились на другую строку при выводе в отчеты или печатные формы.
Проанализируем ситуации, в которых наличие символа Символы.НПП приводит к трудноуловимым ошибкам в коде:
Формат, с обычной строковой константой, условие вернет Ложь. Например, выражение СтрокаДаты = "24 апреля 2017 г." не сработает, так как в литерале задан обычный пробел (код 32), а в переменной содержится код 160.СтрНайти или наложение отборов может давать пустой результат, если пользователь вводит строку поиска с обычной клавиатуры.Рассмотрим самый надежный и простой способ избежать появления неразрывных пробелов. Вместо локального формата ДЛФ зададим точный шаблон даты с помощью параметра ДФ. Все символы и пробелы, явно указанные внутри одинарных кавычек строки формата, платформа сохраняет без изменений:
ФорматированнаяДата = Формат(ТекущаяДата(), "ДФ='d MMMM yyyy г.'");
Сообщить(ФорматированнаяДата);
В этом случае между годом и буквой «г.» гарантированно запишется стандартный пробел с кодом 32, что полностью исключит проблемы со сравнением и выгрузкой данных.
Если в алгоритме требуется сохранить именно системное локальное представление даты через ДЛФ, обработаем готовую строку с помощью функции СтрЗаменить. Заменим спецсимвол Символы.НПП на стандартный пробел:
ФорматированнаяДата = Формат(ТекущаяДата(), "ДЛФ=DD");
ФорматированнаяДата = СтрЗаменить(ФорматированнаяДата, Символы.НПП, " ");
Посмотрим на альтернативный вариант замены через код символа, который дает абсолютно аналогичный результат:
ФорматированнаяДата = СтрЗаменить(ФорматированнаяДата, Символ(160), " ");
Разберем вариант для типовых конфигураций, разработанных на базе Библиотеки стандартных подсистем. Чтобы не писать собственные обработчики строк, применим готовую экспортную функцию общего модуля:
ФорматированнаяДата = Формат(ТекущаяДата(), "ДЛФ=DD");
ФорматированнаяДата = СтроковыеФункцииКлиентСервер.УдалитьНеразрывныеПробелы(ФорматированнаяДата);
Этот метод заменяет все неразрывные пробелы в переданном тексте на стандартные пробелы пробельной клавиши, обеспечивая корректность дальнейшей строковой обработки.
В задачах, где требуется полностью изолировать логику формирования представления даты от настроек платформы и региональных стандартов, соберем строку вручную с помощью СтрШаблон:
ДатаДляВывода = ТекущаяДата();
ФорматированнаяДата = СтрШаблон("%1 %2 %3 г.",
День(ДатаДляВывода),
Формат(ДатаДляВывода, "ДФ=MMMM"),
Формат(Год(ДатаДляВывода), "ЧГ=0"));
Обратим внимание на параметр ЧГ=0 при форматировании года: он отключает группировку разрядов числа, предотвращая подстановку неразрывного пробела между тысячами и сотнями.