Как преобразовать дату формата 2025-10-20 13:40:36.388998+03 в дату 1С

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

При интеграции 1С с современными веб-сервисами, такими как API Яндекса, интеграция с Jira через REST API, или при выгрузке данных в Google Таблицы, разработчики часто сталкиваются с форматом даты и времени, который платформа 1С "из коробки" не понимает. Типичный пример такой строки: "2025-10-20 13:40:36.388998+03". Здесь мы видим дату, время, микросекунды (6 знаков после точки) и смещение часового пояса в сокращенном формате.

Проблема заключается в том, что стандартный конструктор Дата() в 1С ожидает либо строку формата "ГГГГММДДЧЧММСС", либо локализованную строку, а встроенные механизмы JSON-парсинга (важные, если вы реализуете экспорт документов в JSON) требуют строгого соответствия ISO 8601. В этой статье мы подробно разберем несколько способов решения данной задачи, проанализируем нюансы каждого подхода и выберем наиболее стабильный.

Почему стандартные методы 1С не работают напрямую?

Давайте выясним причину, по которой простые функции пасуют перед такой строкой. Рассмотрим основные препятствия:

  1. Разделитель "Пробел": В стандарте ISO 8601 между датой и временем должен стоять символ T. Пробел часто используется в SQL-базах, но 1С (через XMLЗначение) его не воспринимает, что может стать помехой.
  2. Микросекунды: Платформа 1С хранит дату с точностью до секунды. Наличие точки и шести знаков после нее (микросекунд) вызывает ошибку при попытке прямого преобразования.
  3. Формат часового пояса: Обозначение +03 является сокращенным. Для корректной десериализации XML/JSON часто требуется полный формат +03:00.

Способ 1. Использование регулярных выражений (для платформы 8.3.23 и выше)

Начиная с версии платформы 8.3.23, в 1С появились мощные инструменты для работы со строками — функции СтрЗаменитьПоРегулярномуВыражению и СтрНайтиПоРегулярномуВыражению. Наряду с такими задачами, как интеллектуальное сравнение строк по алгоритму Левенштейна, это наиболее элегантный и современный способ. Проанализируем ситуацию: нам нужно извлечь группы (год, месяц, день, часы, минуты, секунды) и собрать их в понятный для 1С формат.

Рассмотрим пример функции, которая выполняет такое преобразование за одну операцию:


Функция ПреобразоватьДатуРегуляркой(Знач ДатаСтрокой) Экспорт
    // Паттерн описывает: ГГГГ-ММ-ДД Пробел ЧЧ:ММ:СС .Микросекунды(опционально) Смещение
    Паттерн = "^(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?([+-]\d{2})(?::\d{2})?$";
    // Меняем местами части строки, чтобы получить формат ДД.ММ.ГГГГ ЧЧ:ММ:СС
    РезультатСтрокой = СтрЗаменитьПоРегулярномуВыражению(ДатаСтрокой, Паттерн, "$3.$2.$1 $4:$5:$6");
    
    Возврат Дата(РезультатСтрокой);
КонецФункции

В данном коде мы игнорируем микросекунды и часовой пояс, просто "выкусывая" основные компоненты даты. Это удобно, если вы точно знаете, что время уже передано в нужном вам часовом поясе (например, по Москве).

Способ 2. Нормализация под ISO 8601 и XMLЗначение

Если нам необходимо учитывать часовой пояс и мы хотим использовать встроенный механизм XMLЗначение, строку нужно предварительно "причесать". Этот метод более универсален, так как он заставит платформу саму вычислить итоговое время с учетом смещения. Разберем по шагам, что нужно сделать:

  1. Заменить пробел на символ T.
  2. Отрезать микросекунды (все, что между точкой и знаком плюс/минус).
  3. Дополнить короткое смещение часового пояса (например, +03) до полного (+03:00).

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


Функция ПреобразоватьВДатуISO(Знач ВходнаяСтрока) Экспорт
    // 1. Заменяем пробел на T
    Т = СтрЗаменить(ВходнаяСтрока, " ", "T");
    
    // 2. Обрабатываем микросекунды и часовой пояс
    // Ищем позицию точки и позицию знака смещения
    ПозТочки = СтрНайти(Т, ".");
    ПозПлюса = СтрНайти(Т, "+");
    ПозМинуса = СтрНайти(Т, "-");
    
    ПозЗнака = ?(ПозПлюса > 0, ПозПлюса, ПозМинуса);
    
    Если ПозТочки > 0 И ПозЗнака > ПозТочки Тогда
        // Удаляем часть с микросекундами
        Т = Лев(Т, ПозТочки - 1) + Сред(Т, ПозЗнака);
    КонецЕсли;
    
    // 3. Исправляем часовой пояс (если +03, делаем +03:00)
    Если СтрДлина(Т) - СтрНайти(Т, "+") = 2 Или СтрДлина(Т) - СтрНайти(Т, "-") = 2 Тогда
        Т = Т + ":00";
    КонецЕсли;
    
    // Теперь строка вида "2025-10-20T13:40:36+03:00" корректно прочитается
    Возврат XMLЗначение(Тип("Дата"), Т);
КонецФункции

Способ 3. Универсальный разбор через массив (защищенный метод)

Рассмотрим ситуацию, когда формат может слегка плавать (например, отсутствуют ведущие нули или микросекунды то есть, то нет). В этом случае мы можем применить "метод грубой силы": заменить все возможные разделители на пробелы, разбить строку в массив и собрать дату из фрагментов. Подобная гибкость часто требуется, когда выполняется импорт данных из Excel, CSV или TXT.

Проанализируем этот подход:


Функция ПреобразоватьДатуУниверсально(Знач ВходнаяСтрока) Экспорт
    // Заменяем все нецифровые символы на пробелы
    Стр = ВходнаяСтрока;
    Стр = СтрЗаменить(Стр, "-", " ");
    Стр = СтрЗаменить(Стр, ":", " ");
    Стр = СтрЗаменить(Стр, ".", " ");
    Стр = СтрЗаменить(Стр, "+", " ");
    
    МассивЧастей = СтрРазделить(Стр, " ", Ложь);
    
    Если МассивЧастей.Количество() < 6 Тогда
        Возврат Дата(1,1,1);
    КонецЕсли;
    
    // Собираем в формате ГГГГММДДЧЧММСС
    Строка1С = МассивЧастей[0] + 
               Прав("0" + МассивЧастей[1], 2) + 
               Прав("0" + МассивЧастей[2], 2) + 
               Прав("0" + МассивЧастей[3], 2) + 
               Прав("0" + МассивЧастей[4], 2) + 
               Прав("0" + МассивЧастей[5], 2);
               
    Возврат Дата(Строка1С);
КонецФункции

Важный момент: Данный метод полностью игнорирует часовой пояс. Он просто берет "цифры как есть". Если ваш источник данных (API) всегда отдает время в UTC или всегда в вашем местном поясе, этот способ будет самым быстрым и надежным.

Подведение итогов и рекомендации

Мы рассмотрели три принципиально разных подхода. Какой выбрать? выясним это прямо сейчас:

Помните, что 1С не поддерживает хранение миллисекунд в стандартном типе Дата. Если точность до долей секунды критически важна для бизнес-логики (например, для высокочастотной торговли или детального логирования), вам придется хранить дробную часть отдельно в числовом реквизите или в виде строки.

← На главную