Как правильно передать дату и время в формате dateTime через XDTO в 1С:Предприятии?

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

При интеграции систем 1С со сторонними веб-сервисами и базами данных разработчики регулярно сталкиваются с необходимостью передачи даты и времени. Стандартом обмена в XML-документах для этого служит формат dateTime (определенный консорциумом W3C). Попытки сформировать эту строку вручную с помощью встроенной функции Формат() часто приводят к неявным ошибкам валидации XDTO, таким как "Несоответствие типов XDTO: Значение не соответствует простому типу".

В этой статье мы подробно разберем, почему возникают такие ошибки, как устроена работа с типами даты/времени в платформе 1С, и рассмотрим правильные механизмы заполнения свойств XDTO для бесперебойного обмена данными.

Выясняем причину: почему ручное форматирование даты ломает XDTO?

Рассмотрим классический пример, с которого часто начинают разработчики. Допустим, у нас есть свойство XDTO-пакета с именем EstimatedDeliveryDate, имеющее тип dateTime (пространство имен http://www.w3.org/2001/XMLSchema). По спецификации XML Schema данный тип должен иметь вид ГГГГ-ММ-ДДTЧЧ:ММ:СС (например, 2018-09-19T16:25:04), где латинская буква T выступает обязательным разделителем между датой и временем.

Попытка установить значение свойства через ручное форматирование выглядит так:


// Попытка ручного форматирования строки с разделителем 'T'
ХДТОХедер.EstimatedDeliveryDate = Формат(Объект.ДатаПриходаУхода, "ДФ='гггг-ММ-ддТЧЧ:мм:сс'");

Этот код приводит к падению платформы с ошибкой:

"Ошибка проверки данных XDTO: Значение: '2018-09-19Т16:25:04' не соответствует простому типу".

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

Если же мы уберем разделитель T и запишем дату в более простом строковом формате, платформа все равно вернет ошибку несовместимости типов, либо (в редких случаях нестрогой проверки) запишет пустую дату 0001-01-01 или дату без учета времени.

---

Решение №1: Прямая передача объекта типа Дата (Рекомендуемый способ)

Самый простой, лаконичный и архитектурно правильный способ — это передача стандартного объекта 1С Дата напрямую в свойство XDTO-объекта. Платформа 1С «под капотом» сама знает правила сериализации своих типов данных в XML-форматы. Она автоматически переведет дату в нужный текстовый вид и самостоятельно подставит букву T в качестве разделителя при генерации XML-пакета.

Давайте посмотрим на пример правильного заполнения свойства:


// Прямая передача нативного типа Дата в объект XDTO
ХДТОХедер.EstimatedDeliveryDate = Объект.ДатаПриходаУхода;

В этом случае при выгрузке XML платформа сама сформирует валидную строку:

<EstimatedDeliveryDate>2018-09-19T16:25:04</EstimatedDeliveryDate>

Никаких ошибок валидации не возникнет, так как фабрика XDTO успешно сопоставит тип данных 1С Дата с типом схемы dateTime.

---

Решение №2: Использование функции XMLСтрока()

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

Разберем пример ее использования:


// Преобразование даты в формат XML-строки
СтроковоеПредставлениеДаты = XMLСтрока(Объект.ДатаПриходаУхода);
// На выходе получим строку вида: "2018-09-19T16:25:04"

Обратите внимание: если вы присвоите результат работы функции XMLСтрока() свойству XDTO, имеющему строгий тип dateTime, вы можете вновь столкнуться с ошибкой валидации на некоторых конфигурациях и релизах платформы, так как функция возвращает тип Строка. Используйте XMLСтрока() только для полей, которые в схеме XDTO объявлены как текстовые (string), либо при прямой записи в XML-документ.

---

Разбор сложных случаев: Часовые пояса (Timezone Offset)

Многие современные API (особенно зарубежные веб-сервисы) требуют передачи времени строго с указанием часового пояса в формате ISO 8601 (например, 2018-11-28T14:00:07+03:00 или 2018-11-28T11:00:07Z для UTC).

Здесь кроется важная архитектурная особенность 1С: встроенный тип данных Дата в 1С не хранит информацию о часовом поясе.

Если вы передадите объект Дата напрямую в XDTO-свойство типа dateTime, то в итоговом XML часовой пояс указан не будет. Это может привести к тому, что принимающая сторона неверно интерпретирует ваше локальное время.

Рассмотрим, как решить эту проблему в зависимости от структуры вашей XDTO-схемы:

Вариант А: Если тип свойства в схеме — string (строка)

Если схема веб-сервиса позволяет передавать дату как строку, мы можем вручную сформировать дату со смещением, используя функцию XMLСтрока() и конкатенацию:


// Формируем дату со смещением московского часового пояса (+03:00)
ХДТОХедер.EstimatedDeliveryDate = XMLСтрока(ТекущаяДата()) + "+03:00";
// Результат в XML: 2018-11-28T14:00:07+03:00

Вариант Б: Если тип свойства строго dateTime и схему менять нельзя

Если схема требует строго dateTime, попытка дописать строку со смещением (+03:00) напрямую вызовет ошибку валидации фабрики. В этом случае лучшей практикой является приведение времени к универсальному координированному времени (UTC) перед отправкой:


// Переводим местное время сеанса в UTC (Гринвич)
ДатаВФорматеUTC = УниверсальноеВремя(Объект.ДатаПриходаУхода);

// Передаем дату в XDTO
ХДТОХедер.EstimatedDeliveryDate = ДатаВФорматеUTC;

Хотя в итоговом XML не будет символа Z на конце, большинство принимающих систем по умолчанию трактуют полученную дату без указания смещения как UTC (или это регламентируется правилами интеграции сторонних систем).

---

Работа с миллисекундами

Спецификация W3C для типа dateTime поддерживает дробную часть секунды (миллисекунды, например, 2018-09-19T16:25:04.123). Стандартный тип Дата в 1С имеет точность только до одной секунды.

Если внешняя система присылает вам данные с миллисекундами, при чтении XML через фабрику XDTO платформа 1С автоматически отбросит дробную часть секунд и запишет в базу стандартную дату.

Если же внешнее API строго требует передачи миллисекунд от вас, вам придется переопределить это поле в схеме XDTO как string и формировать его вручную программным путем.

---

Рекомендации по проектированию веб-сервисов в 1С

Для минимизации ошибок при работе с датами рекомендуем придерживаться следующих правил:

  1. Доверяйте платформе: При заполнении объектов XDTO всегда передавайте стандартные объекты типа Дата. Не пытайтесь форматировать их через функцию Формат().
  2. Контролируйте типы в схеме: В пакетах XDTO для хранения дат используйте типы dateTime (если важны и дата, и время), date (если нужно передать только день без времени) или time (только время). Платформа 1С автоматически отсечет лишние компоненты при выгрузке типов date и time.
  3. Используйте UTC при обмене: Чтобы избежать путаницы со временем на серверах, находящихся в разных часовых поясах, всегда приводите дату к универсальному времени функцией УниверсальноеВремя() перед ее записью в объект XDTO.

Применяя эти подходы, вы обеспечите быструю и корректную сериализацию данных, избавив себя от рутины ручного парсинга строк и снизив вероятность появления ошибок интеграции до нуля.

← На главную