При обмене данными между SQL-базами и 1С часто возникает проблема: при получении строки даты вида 2021-05-04T00:00:00.000Z стандартные функции 1С прибавляют смещение часового пояса сервера. В результате вместо ожидаемой даты мы получаем время, сдвинутое на несколько часов вперед (например, +3 часа для московского времени). Давайте разберем, почему так происходит и как с этим бороться.
Проблема кроется в стандарте ISO 8601. Символ Z в конце строки означает «Zulu time» или UTC (всемирное координированное время). Когда платформа 1С видит этот маркер при преобразовании строки в тип Дата, она «понимает», что время передано в UTC, и автоматически конвертирует его в локальное время сеанса, используя настройки часового пояса сервера или компьютера, на котором выполняется код.
Для бизнес-логики это часто становится проблемой, так как нам нужно получить «чистую» дату из базы данных без автоматического пересчета часовых поясов.
Самый простой и надежный способ — удалить символ Z (или все, что идет после него) перед тем, как передавать строку в функцию преобразования. В этом случае платформа 1С будет воспринимать строку как локальную дату без указания часового пояса и не станет применять никакие смещения.
Рассмотрим, как это реализовать программно:
// Исходная строка из SQL
СтрокаДаты = \"2021-05-04T00:00:00.000Z\";
// Отрезаем суффикс, если он присутствует
Если Прав(СтрокаДаты, 1) = \"Z\" Тогда
СтрокаДаты = Лев(СтрокаДаты, СтрДлина(СтрокаДаты) - 1);
КонецЕсли;
// Теперь преобразуем очищенную строку
ДатаОбъекта = XMLЗначение(Тип(\"Дата\"), СтрокаДаты);
Этот метод позволяет корректно получить дату 04.05.2021 00:00:00 без принудительного добавления 3 часов.
Если данные приходят в формате JSON, часто возникает соблазн использовать встроенный метод ПрочитатьДатуJSON. Однако важно помнить, что этот метод строго придерживается стандартов. Если в строке присутствует маркер Z или указано смещение (например, +03:00), метод приведет дату к локальному времени сеанса.
Пример использования метода ПрочитатьДатуJSON:
// Этот код приведет к смещению времени, если в строке есть маркер UTC
ДатаОбъекта = ПрочитатьДатуJSON(СтрокаДаты, ФорматДатыJSON.ISO);
Поэтому данный метод подходит только в том случае, если вы сознательно хотите привести время к часовому поясу вашего сервера. Если же вам нужно «чистое» значение — используйте первый способ с предварительной очисткой строки.
ГГГГММДДЧЧММСС — это исключит любую неоднозначность при интерпретации на стороне 1С.2019-03-10T13:14:15 (локальная дата), 2019-03-10T13:14:15+04:00 (со смещением) и 2019-03-10T09:14:15Z (в UTC). Ваша задача — определить, какой именно формат вы получаете, и при необходимости унифицировать его до «чистой» строки.Z на требуемое смещение с помощью функции СтрЗаменить (например, на +03:00). Тогда 1С интерпретирует дату с учетом именно этого смещения.Таким образом, для большинства задач по импорту данных из SQL лучшим решением будет очистка строки от маркера UTC. Это обеспечит стабильное поведение платформы и полное соответствие полученных данных тем, что хранятся в базе-источнике.