При интеграции 1С с внешними системами (веб-сайтами, REST API, сторонними базами данных) разработчики регулярно сталкиваются с необходимостью обработки дат. Очень часто внешние системы передают дату и время в международном стандарте ISO 8601. Типичный пример такой строки: "2020-03-20T19:12:43", где символ T выступает разделителем между датой и временем. Для быстрого развертывания обмена данными с веб-сервисами можно использовать готовый шаблон интеграции 1С со сторонними приложениями через HTTP и JSON.
В этой статье мы подробно разберем, как быстро, элегантно и без «велосипедов» преобразовать подобную строку в стандартный тип данных Дата в среде 1С:Предприятие. Мы рассмотрим встроенные платформенные функции, особенности работы с часовыми поясами, миллисекундами, а также разберем распространенные ошибки при использовании сторонних библиотек.
Иногда начинающие разработчики пытаются решить задачу «в лоб»: разбирать строку посимвольно, использовать функции работы с подстроками (Лев, Сред, Прав), заменять символы разделителей или писать сложные запросы с регулярными выражениями и шаблонами. Посмотрим на пример такого перегруженного кода:
// Пример неоптимального и сложного разбора строки
Если СтрДлина(ЗначениеСайта) = 19 И Сред(ЗначениеСайта, 11, 1) = "T" Тогда
ЗначениеСайта = СтрЗаменить(ЗначениеСайта, ":", "");
ЗначениеСайта = СтрЗаменить(ЗначениеСайта, "-", "");
ЗначениеСайта = СтрЗаменить(ЗначениеСайта, "T", "");
Попытка
Возврат Дата(ЗначениеСайта);
Исключение
Возврат Неопределено;
КонецПопытки;
КонецЕсли;
Этот подход имеет множество критических недостатков:
Платформа 1С предлагает готовые, быстрые и надежные инструменты для решения этой задачи в одну строку. Рассмотрим их подробнее.
Наиболее лаконичный и универсальный способ преобразовать ISO-строку в дату — использовать встроенную функцию платформы XMLЗначение. Этот метод работает на уровне платформы и задействует быстрые механизмы десериализации XML, для которых формат ISO 8601 является родным (соответствует базовому типу dateTime).
Разберем пример кода:
СтрокаДаты = "2020-03-20T19:12:43";
ДатаРезультат = XMLЗначение(Тип("Дата"), СтрокаДаты);
// В результате переменная ДатаРезультат примет значение: 20.03.2020 19:12:43
Этот метод невероятно удобен: он не требует подключения дополнительных модулей, работает как на клиенте, так и на сервере, и автоматически валидирует корректность переданной строки.
Если ваша задача связана с разбором данных, полученных в формате JSON, идеальным решением станет использование специализированной функции ПрочитатьДатуJSON. Этот метод появился в платформе специально для стандартизации работы со строковыми представлениями дат.
Проанализируем пример применения этой функции:
СтрокаДаты = "2020-03-20T19:12:43";
ДатаРезультат = ПрочитатьДатуJSON(СтрокаДаты, ФорматДатыJSON.ISO);
// Результат: 20.03.2020 19:12:43
Второй параметр функции — системное перечисление ФорматДатыJSON.ISO — явно указывает платформе, что строку нужно парсить в соответствии со стандартом ISO 8601.
Часто разработчики совершают лишнюю работу: сначала с помощью ПрочитатьJSON разбирают весь входящий JSON-пакет в структуру 1С, а затем циклом обходят полученные свойства, конвертируя строки дат через ПрочитатьДатуJSON. На самом деле платформа умеет делать это автоматически прямо в момент чтения документа.
Давайте посмотрим, как настроить автоматическое преобразование всех полей с датами при чтении JSON:
// Предположим, у нас есть JSON-строка, где "создано" — это дата в формате ISO
СтрокаJSON = "{""Имя"": ""Документ №1"", ""ДатаСоздания"": ""2020-03-20T19:12:43""}";
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
// Указываем платформе, какие свойства структуры нужно сразу приводить к типу Дата
МассивСвойствДаты = Новый Массив;
МассивСвойствДаты.Добавить("ДатаСоздания");
Данные = ПрочитатьJSON(Чтение, Ложь, МассивСвойствДаты, ФорматДатыJSON.ISO);
Чтение.Закрыть();
// Теперь Данные.ДатаСоздания — это уже готовый тип Дата, а не строка!
Этот подход экономит процессорное время и делает ваш код чистым и профессиональным. Для проверки структуры данных и ускорения разработки алгоритмов парсинга можно использовать инструмент для форматирования, валидации и генерации кода 1С для работы с JSON.
При работе с внешними интеграциями мало просто сконвертировать строку в дату. Необходимо учитывать специфику обработки времени платформой 1С. Например, при обмене данными с торговыми площадками можно использовать готовые модули для интеграции 1С с Ozon, Wildberries и Яндекс.Маркетом, которые берут на себя всю работу по передаче заказов и синхронизации сведений.
Если входная строка содержит информацию о часовом поясе (например, суффикс Z для UTC или смещение +03:00), поведение функций XMLЗначение и ПрочитатьДатуJSON меняется:
"2020-03-20T19:12:43" преобразуется в локальное время компьютера "один в один". Получим 19:12:43."2021-03-09T17:17:54+04:00", а ваш сервер 1С работает в московском часовом поясе (UTC+3), платформа автоматически сдвинет время на разницу поясов. На выходе вы получите пересчитанное локальное время сеанса: 16:17:54.Стандарт ISO 8601 допускает передачу долей секунд (например, "2020-03-20T19:12:43.620"). Стандартный тип Дата в 1С хранит время только с точностью до секунды.
При использовании XMLЗначение или ПрочитатьДатуJSON платформа выполнит автоматическое математическое округление секунд. В нашем примере 43.620 округлится в большую сторону, и вы получите время 19:12:44. Если вам жизненно необходима точность до миллисекунд (например, для ведения логов высокой точности), вам придется сохранять число миллисекунд отдельно, предварительно распарсив исходную строку строковыми методами.
Многие разработчики по привычке обращаются к функциям БСП, например, к популярной функции СтроковыеФункцииКлиентСервер.СтрокаВДату().
Важное предостережение: эта функция не предназначена для разбора формата ISO 8601 с разделителем T. Она умеет работать только с локализованными представлениями дат (например, "20.03.2020 19:12:43"). При попытке передать туда ISO-строку функция вернет пустую дату. Для конвертации всегда используйте описанные выше платформенные методы.
При этом в БСП есть очень полезный обратный механизм для выгрузки даты из 1С во внешнюю систему в формате ISO со смещением:
СтрокаISO = ОбщегоНазначения.ПредставлениеЛокальнойДатыСоСмещением(ТекущаяДата());
// На выходе получим строку вида: "2023-10-27T15:30:00+03:00"
В редких случаях, когда разбор XML-пакетов происходит в динамическом потоке без выделения строковых переменных, можно воспользоваться системным Сериализатором XDTO. Поскольку формат ISO соответствует базовому XML-типу dateTime, можно выполнить чтение следующим образом:
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку("<Дата xmlns=""http://www.w3.org/2001/XMLSchema"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xs:type=""dateTime"">" + СтрокаДаты + "</Дата>");
Результат = СериализаторXDTO.ПрочитатьXML(Чтение, Тип("Дата"));
Этот способ более громоздкий, но он наглядно демонстрирует, как глубоко стандарты XML и ISO интегрированы в ядро платформы 1С.
Для преобразования строки формата ISO 8601 в дату в 1С не нужно писать громоздкие парсеры. Достаточно использовать:
XMLЗначение(Тип("Дата"), ВашаСтрока) — универсально и быстро.ПрочитатьДатуJSON(ВашаСтрока, ФорматДатыJSON.ISO) — идеально при обработке данных JSON.