Как преобразовать дату в формат ISO 8601 с миллисекундами и смещением часового пояса в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними веб-сервисами, работающими по стандартам REST или SOAP, разработчики часто сталкиваются с жестким требованием к формату даты. Стандарт XML Schema и спецификация ISO 8601 предполагают запись вида 2022-06-01T10:08:36.243+01:00. Однако штатные функции 1С, такие как XMLСтрока() или Формат(), выдают либо локальное время без часового пояса, либо не включают миллисекунды.

В этой статье мы подробно разберем, почему возникает эта сложность, и рассмотрим несколько способов формирования строки даты с нужной точностью и смещением.

Ограничение типа Дата в платформе 1С

Прежде чем переходить к коду, проанализируем ситуацию с типами данных. В языке 1С:Предприятие 8 тип Дата всегда содержит значения с точностью до секунды. В переменной этого типа физически отсутствуют миллисекунды. Именно поэтому ни одна встроенная функция сериализации не может «достать» их из обычной даты. Если внешнее API требует наличие миллисекунд (например, .243), у нас есть два варианта: либо подставлять фиксированное значение (например, .000), если точность не критична, либо использовать внешние инструменты для получения системного времени.

Способ 1. Использование функции ЗаписатьДатуJSON с постобработкой

Функция ЗаписатьДатуJSON — один из самых мощных инструментов для работы с форматом ISO в 1С. Она умеет автоматически вычислять смещение локального времени относительно UTC. Рассмотрим пример кода:


// Пример получения базовой строки ISO со смещением
ДатаДляПреобразования = ТекущаяДата();
СтрокаJSON = ЗаписатьДатуJSON(ДатаДляПреобразования, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением);
// Результат будет примерно таким: "2020-06-27T18:27:44+06:00"

Как мы видим, в результате отсутствуют миллисекунды. Чтобы их добавить, воспользуемся методом строковых манипуляций. Нам нужно найти символ «+» (начало смещения) и вставить перед ним наши миллисекунды. Разберем этот алгоритм по шагам:


Функция СформироватьДатуСМиллисекундами(Знач ВхДата, Знач Миллисекунды = "000") Экспорт
    // Получаем базу через JSON
    СтрокаISO = ЗаписатьДатуJSON(ВхДата, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением);
    
    // Удаляем кавычки, которые добавляет JSON-сериализатор
    СтрокаISO = СтрЗаменить(СтрокаISO, """", "");
    
    // Вставляем миллисекунды перед знаком смещения (+ или -)
    // Сначала найдем позицию знака часового пояса
    ПозицияЗнака = СтрНайти(СтрокаISO, "+");
    Если ПозицияЗнака = 0 Тогда
        ПозицияЗнака = СтрНайти(СтрокаISO, "-"); // Проверка на отрицательное смещение
    КонецЕсли;
    
    Если ПозицияЗнака > 0 Тогда
        Результат = Лев(СтрокаISO, ПозицияЗнака - 1) + "." + Миллисекунды + Сред(СтрокаISO, ПозицияЗнака);
    Иначе
        Результат = СтрокаISO + "." + Миллисекунды; // Если смещение не определено
    КонецЕсли;
    
    Возврат Результат;
КонецФункции

Способ 2. Программное вычисление смещения часового пояса

Если по каким-то причинам использование JSON-функций неудобно, мы можем собрать строку вручную. Главная сложность здесь — корректно определить смещение часового пояса (Timezone Offset). В 1С это делается путем сравнения локального времени сервера и универсального времени (UTC). Выясним причину разницы и сформируем хвост строки:


Функция ПолучитьСтрокуСмещения()
    СекундСмещения = ТекущаяДата() - ТекущаяУниверсальнаяДата();
    
    Знак = ?(СекундСмещения >= 0, "+", "-");
    АбсСекунд = ?(СекундСмещения >= 0, СекундСмещения, -СекундСмещения);
    
    Часов = Цел(АбсСекунд / 3600);
    Минут = (АбсСекунд % 3600) / 60;
    
    Возврат Знак + Формат(Часов, "ЧЦ=2; ЧВН=") + ":" + Формат(Минут, "ЧЦ=2; ЧВН=");
КонецФункции

// Сборка итоговой строки
Милисекунды = "243";
ИтоговаяСтрока = Формат(ТекущаяДата(), "ДФ=yyyy-MM-ddTHH:mm:ss") + "." + Милисекунды + ПолучитьСтрокуСмещения();

Этот метод хорош тем, что он не зависит от настроек сериализации JSON и работает на любой версии платформы 8.3.

Способ 3. Использование .NET (System.DateTime) для Windows-серверов

Если ваша база работает на ОС Windows, мы можем воспользоваться объектами .NET через механизм COM-соединения. Это самый надежный способ получить реальные миллисекунды системы и сразу отформатировать их по стандарту ISO без лишних манипуляций со строками.

Посмотрим на пример реализации:


Попытка
    // Создаем объект системного времени .NET
    DateTime = Новый COMОбъект("System.DateTime");
    // Получаем текущее время
    Now = DateTime.Now;
    // Используем специфическую маску: K — это смещение, fff — миллисекунды
    ФорматированнаяДата = Now.ToString("yyyy-MM-ddTHH:mm:ss.fffK");
    Сообщить(ФорматированнаяДата);
Исключение
    Сообщить("Метод доступен только в среде Windows с установленным .NET Framework");
КонецПопытки

Важный момент: Символ K в методе ToString автоматически определяет, нужно ли писать Z (для UTC) или +HH:MM (для локального времени), основываясь на свойствах объекта DateTime.

Способ 4. Работа через XDTO (Native XML)

Рассмотрим ситуацию, когда дата передается внутри XML-документа. Если вы используете фабрику XDTO и тип свойства в схеме (XSD) определен как dateTime, 1С попытается выполнить форматирование автоматически.

Проанализируем пример записи через XDTO:

  1. Создайте тип объекта в пакете XDTO с типом dateTime (пространство имен http://www.w3.org/2001/XMLSchema).
  2. Присвойте значение свойству: ОбъектXDTO.ДатаСоздания = ТекущаяДата();.
  3. Запишите XML через ЗаписатьXML().

Однако помните, что встроенный механизм XDTO в 1С часто игнорирует смещение часового пояса, если оно не задано явно через специальные типы. Поэтому для строгих API ручная сборка строки (Способ 1 или 2) остается наиболее предсказуемым вариантом. При необходимости подготовить схему данных можно использовать обработку для автоматического формирования пакетов XSD.

Резюме

Подводя итог, можно выделить следующие рекомендации:

Используя эти подходы, вы сможете корректно интегрировать 1С с любыми современными информационными системами, требующими строгого соблюдения стандарта ISO 8601. Для интерактивной проверки отправки сформированных запросов прямо из программы подойдёт инструмент для тестирования REST API в 1С.

← На главную