Как преобразовать строку формата ISO 8601 в дату 1С

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

В современной практике интеграции систем формат ISO 8601 (например, 2021-03-09T17:17:54.620+03:00) является стандартом де-факто для передачи моментов времени. Однако встроенный в 1С тип Дата имеет свои особенности, и простое присваивание строки переменной типа Дата не сработает. Разберем детально, как правильно и эффективно выполнить это преобразование, учитывая часовые пояса, миллисекунды и различные программные контексты.

Способ 1: Использование системной функции XMLЗначение

Этот метод считается одним из самых быстрых и надежных, так как он опирается на внутренние механизмы платформы 1С по работе с типами данных XML Schema (XSD). Функция XMLЗначение автоматически распознает разделители «-», «T» и «:», а также корректно обрабатывает смещение часового пояса.

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


// Входящая строка в формате ISO 8601
СтрокаДаты = "2021-03-09T17:17:54.620+03:00";

// Преобразование с использованием типа Дата
ДатаРезультат = XMLЗначение(Тип("Дата"), СтрокаДаты);

// Результат: 09.03.2021 17:17:55 (с учетом округления миллисекунд)
Сообщить(ДатаРезультат);

Важный нюанс: Обратите внимание, что тип Дата в 1С хранит значения только до секунды. Если в строке указаны миллисекунды (как в примере .620), платформа применит математическое округление. Значение 54.620 превратится в 55 секунд. Если вам критически важно сохранять миллисекунды, их придется извлекать отдельно и хранить в числовом поле.

Способ 2: Использование механизмов JSON

Начиная с версии 8.3.6, в 1С появились мощные инструменты для работы с JSON. Метод ПрочитатьДатуJSON идеально подходит для обработки строк в формате ISO, так как этот формат является стандартным для JSON-сериализации дат.

Проанализируем алгоритм работы через этот механизм. Важно помнить, что функция работает не напрямую со строкой, а через объект ЧтениеJSON:


// Исходная строка
ДатаСтрокой = "2021-03-09T17:17:54.620+03:00";

// Для корректного чтения JSON строка должна быть в кавычках
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку("""" + ДатаСтрокой + """");

// Читаем дату в формате ISO
ДатаРезультат = ПрочитатьДатуJSON(Чтение, ФорматДатыJSON.ISO);
Чтение.Закрыть();

Сообщить(ДатаРезультат);

Этот метод удобен тем, что он строго следует спецификациям и корректно обрабатывает суффикс Z (UTC время) или числовые смещения поясов.

Способ 3: Функции Библиотеки Стандартных Подсистем (БСП)

Если ваша конфигурация разработана на базе БСП, мы можем воспользоваться готовыми методами из общих модулей. Это избавляет от необходимости писать низкоуровневый код обработки строк или инициализировать объекты чтения.

Посмотрим на пример использования модуля СтроковыеФункцииКлиентСервер:


// Использование функции БСП
ДатаРезультат = СтроковыеФункцииКлиентСервер.СтрокаВДату("2021-03-09T17:17:54", "YYYY-MM-DDThh:mm:ss");

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

Способ 4: Ручной разбор и прямое приведение типа

В некоторых случаях, когда производительность критична и мы точно знаем, что формат строки неизменен (например, ГГГГ-ММ-ДДTЧЧ:ММ:СС), можно прибегнуть к манипуляциям со строкой. Стандартный конструктор Дата() в 1С принимает строку вида "ГГГГММДДЧЧММСС".

Разберем, как подготовить строку для такого конструктора:


// Исходная строка: "2021-03-09T17:17:54"
// Нам нужно получить: "20210309171754"

ИсходнаяСтрока = "2021-03-09T17:17:54";
ЧистаяСтрока = СтрЗаменить(ИсходнаяСтрока, "-", "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, "T", "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, ":", "");

// Теперь можно вызвать конструктор
ДатаРезультат = Дата(ЧистаяСтрока);

Внимание: Этот способ не учитывает часовые пояса. Если в строке передано время в UTC (с символом Z), а ваш сервер находится в зоне +03:00, вы получите «сырое» время без поправки на локальный пояс, что может привести к ошибкам в логике приложения.

Нюансы работы с часовыми поясами

Выясним причину, по которой автоматические методы (XMLЗначение, ПрочитатьДатуJSON) иногда выдают «неожиданный» результат. В 1С тип Дата всегда привязан к локальному времени сеанса или сервера.

  1. Если во входящей строке указано +04:00, а ваш сервер работает в часовом поясе +03:00, 1С автоматически вычтет один час, чтобы привести время к локальному.
  2. Если строка содержит символ Z (UTC), 1С добавит смещение вашего локального пояса к значению.

Если вам нужно получить время «как оно написано» без привязки к поясу, используйте ручной разбор строки (Способ 4), предварительно обрезав часть строки со смещением.

Экзотический способ: Преобразование через запрос

Для общего развития рассмотрим ситуацию, когда дату нужно преобразовать прямо внутри сложного запроса (например, при обработке временных таблиц с текстовыми данными). Хотя это «дикий» способ с точки зрения архитектуры, он демонстрирует гибкость языка запросов.


// Пример логики разбора строки в запросе (фрагмент)
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|   ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1,1,1), СЕКУНДА, 
|   (ВЫБОР ПОДСТРОКА(&Стр, 12, 1) КОГДА ""1"" ТОГДА 10 КОГДА ""2"" ТОГДА 20 ... КОНЕЦ) * 3600
|   ) КАК ДатаИзСтроки";

В реальных задачах лучше использовать XMLЗначение на стороне кода, но понимание того, что строку можно разложить на составляющие в запросе с помощью ПОДСТРОКА, может выручить в специфических условиях.

Рекомендации

Подведем итог и выберем лучшее решение:

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

← На главную