В процессе разработки на платформе 1С:Предприятие программисты часто сталкиваются с ситуацией, когда стандартные функции ведут себя на первый взгляд нелогично. Одной из таких классических проблем является вывод времени 12:00:00 вместо ожидаемых нулей при использовании функции НачалоДня. Начинающему разработчику может показаться, что ошибка кроется в самой функции НачалоДня, однако, как мы выясним далее, причина кроется в нюансах форматирования строки.
В этой статье мы подробно разберем, почему так происходит, изучим важность регистра символов в форматной строке и научимся правильно готовить данные для выгрузки в XML-формат.
Рассмотрим исходный код, который вызвал затруднение у автора вопроса:
ЗаписьXML.ЗаписатьТекст(XMLСтрока(Формат(НачалоДня(ТекущаяДата()), "ДФ='yyyy-MM-dd чч:мм:сс'" )));
Проанализируем ситуацию: функция НачалоДня гарантированно возвращает дату с временной составляющей 00:00:00. Это фундаментальное свойство платформы. Проблема возникает на этапе преобразования этой даты в строку функцией Формат.
В 1С символы форматной строки ДФ крайне чувствительны к регистру. Выясним разницу между ними:
чч (строчные) — это 12-часовой формат представления времени (от 01 до 12). В этом формате полночь (00:00:00) отображается как 12. Именно поэтому в XML-файле автора появилось значение "12:00:00".ЧЧ (прописные/заглавные) — это привычный нам 24-часовой формат (от 00 до 23).Таким образом, для решения проблемы достаточно изменить регистр букв в форматной строке. Посмотрим на исправленный вариант:
// Правильное использование 24-часового формата
Результат = Формат(НачалоДня(ТекущаяДата()), "ДФ='yyyy-MM-dd ЧЧ:мм:сс'");
// Результат: 2024-05-22 00:00:00
Теперь проанализируем конструкцию XMLСтрока(Формат(...)). В среде 1С функция Формат всегда возвращает тип Строка. Функция XMLСтрока, получая на вход строку, просто возвращает её обратно без каких-либо изменений. Следовательно, использование XMLСтрока здесь абсолютно избыточно и только загромождает код.
Рассмотрим более элегантный и правильный с точки зрения стандартов XML способ получения даты. Платформа 1С умеет самостоятельно преобразовывать дату в формат ISO 8601 (стандарт для XML), если передать объект типа Дата напрямую в функцию XMLСтрока.
Сравним два подхода:
// Подход 1: Ручное форматирование (может нарушить стандарт XML)
ЗаписьXML.ЗаписатьТекст(Формат(НачалоДня(ТекущаяДата()), "ДФ='yyyy-MM-dd ЧЧ:мм:сс'"));
// Подход 2: Использование встроенных механизмов сериализации (рекомендуется)
ЗаписьXML.ЗаписатьТекст(XMLСтрока(НачалоДня(ТекущаяДата())));
Во втором случае платформа сформирует строку вида 2024-05-22T00:00:00. Обратите внимание на символ T между датой и временем — это обязательный разделитель согласно стандарту XML. Ручное форматирование через пробел может привести к тому, что внешняя система не сможет корректно прочитать ваш файл.
Когда мы работаем с "началом дня", важно понимать, относительно какого часового пояса мы производим расчет. Выясним разницу между ключевыми функциями:
ТекущаяДата() — возвращает время сервера, на котором выполняется код.ТекущаяДатаСеанса() — возвращает время с учетом часового пояса пользователя, установленного в настройках сеанса.Если ваша база данных распределена по разным регионам, использование ТекущаяДата() для формирования "начала дня" может привести к логическим ошибкам. Например, если сервер находится в Москве, а пользователь во Владивостоке, начало дня по серверу наступит на 7 часов позже, чем ожидает пользователь.
Для технических обменов через XML также крайне полезно использовать универсальное время (UTC). Рассмотрим пример записи даты в формате UTC:
УниверсальнаяДата = УниверсальноеВремя(НачалоДня(ТекущаяДатаСеанса()));
ЗаписьXML.ЗаписатьТекст(XMLСтрока(УниверсальнаяДата));
// Результат будет содержать символ 'Z' в конце: 2024-05-21T21:00:00Z
Чтобы избежать ручного контроля над форматами дат и временем, профессиональным стандартом в 1С является использование механизмов XDTO (XML Data Transfer Objects).
Проанализируем, почему это удобно:
xs:date, то при записи значения 1С сама отсечет временную часть, и вам не придется вызывать НачалоДня.xs:dateTime, механизм XDTO сам позаботится о правильном формате ISO 8601 с учетом часовых поясов.Пример записи через СериализаторXDTO:
// Предположим, у нас есть объект Дата
МояДата = НачалоДня(ТекущаяДата());
// Записываем напрямую в XML через сериализатор
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, МояДата, НазначениеТипаXML.Явное);
Мы выяснили, что "странное" поведение функции НачалоДня в 1С всегда связано не с самой функцией, а с тем, как разработчик интерпретирует результат. Основные правила, которые помогут избежать ошибок в будущем:
ЧЧ в форматной строке для 24-часового формата.Формат() там, где можно применить прямую сериализацию через XMLСтрока().Соблюдение этих простых правил сделает ваш код более надежным, а интеграции с внешними системами — стабильными.