При интеграции систем 1С с внешними приложениями, особенно использующими стек технологий .NET (ASP.NET), часто возникает необходимость передачи даты в специфическом формате Microsoft JSON. Этот формат выглядит как /Date(количество_миллисекунд)/. Одной из распространенных проблем является необходимость передать не просто универсальное время (UTC), а время с конкретным смещением часового пояса (например, московское время +03:00).
В этой статье мы подробно разберем, как управлять смещением зоны, используя стандартные механизмы платформы 1С, и что делать, если стандартных настроек недостаточно.
Для начала проанализируем, как 1С работает с этим форматом. При использовании системного перечисления ФорматДатыJSON.Microsoft, платформа формирует строку, где число внутри скобок представляет собой количество миллисекунд, прошедших с начала эпохи Unix (1 января 1970 года). По умолчанию 1С стремится записывать даты в универсальном формате (UTC), что избавляет от проблем с часовыми поясами, но не всегда подходит принимающей стороне.
Самый правильный и технологичный способ управления выводом даты — использование объекта НастройкиСериализацииJSON. Рассмотрим по шагам, как настроить его для передачи локального времени со смещением.
Выясним причину, почему обычная настройка может не работать. Если мы указываем ВариантЗаписиДатыJSON.УниверсальнаяДата, 1С всегда будет приводить время к UTC. Для сохранения смещения необходимо использовать другой вариант.
// Создаем настройки сериализации
НастройкиСериализации = Новый НастройкиСериализацииJSON;
НастройкиСериализации.ФорматСериализацииДаты = ФорматДатыJSON.Microsoft;
// Указываем вариант записи даты со смещением
НастройкиСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением;
// Пример данных
ДанныеДляЗаписи = Новый Соответствие;
ДанныеДляЗаписи.Вставить("ДатаНачала", ТекущаяДата()); // Локальная дата
// Выполняем запись
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеДляЗаписи, НастройкиСериализации);
РезультатJSON = ЗаписьJSON.Закрыть();
При использовании ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением платформа попытается добавить информацию о часовом поясе. Однако стоит учитывать, что для старого формата Microsoft 1С не всегда добавляет явный суффикс +0300 внутри скобок, так как сам формат изначально предполагал только UTC. Если принимающая сторона требует именно ISO-подобное смещение, рассмотрим альтернативные пути.
Если нам нужно жестко задать смещение (например, мы всегда работаем из Москвы и хотим передать данные именно в этом поясе), мы можем воспользоваться функцией УниверсальноеВремя(). Это позволяет подготовить данные до того, как они попадут в сериализатор.
Посмотрим на пример, когда нам нужно программно вычесть или добавить смещение:
// Допустим, у нас есть локальная дата
ЛокальнаяДата = ТекущаяДата(); // Например, 04.07.2022 00:00:00
// Преобразуем ее, учитывая разницу часовых поясов (например, 3 часа = 10800 секунд)
// Если нам нужно передать дату так, чтобы она интерпретировалась как московская
ДатаДляОтправки = ЛокальнаяДата - 10800;
НастройкиСериализации = Новый НастройкиСериализацииJSON;
НастройкиСериализации.ФорматСериализацииДаты = ФорматДатыJSON.Microsoft;
НастройкиСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.УниверсальнаяДата;
// Теперь при записи 1С преобразует уже скорректированную дату
Метод УниверсальноеВремя(ЛокальнаяДата, "Europe/Moscow") поможет более корректно вычислить разницу, не прибегая к жесткому кодированию секунд.
Проанализируем ситуацию: некоторые старые системы на базе .NET ожидают формат вида \/Date(1535706000000+0300)\/. Стандартная функция ЗаписатьJSON в 1С редко генерирует такой суффикс для формата Microsoft, предпочитая отдавать чистое число миллисекунд. Если внешняя система отказывается понимать данные без «хвоста» часового пояса, придется формировать строку вручную.
Разберем по шагам алгоритм ручного формирования:
/Date()/.
Функция СформироватьMicrosoftDateJSON(Знач ИсходнаяДата, СмещениеСтрокой = "+0300")
// Начало эпохи Unix
ДатаНачалаЭпохи = Дата(1970, 1, 1, 0, 0, 0);
// Получаем разницу в секундах (учитываем UTC)
Секунды = ИсходнаяДата - ДатаНачалаЭпохи;
// Переводим в миллисекунды
Миллисекунды = Секунды * 1000;
// Формируем итоговую строку
Возврат "/Date(" + Формат(Миллисекунды, "ЧГ=0") + СмещениеСтрокой + ")/";
КонецФункции
Используя этот метод, вы гарантируете, что принимающая система получит именно то смещение, которое она ожидает, независимо от настроек сервера 1С.
При работе с часовыми поясами в JSON следует помнить о следующих моментах:
Дата в 1С хранит время с точностью до секунды. При сериализации в Microsoft JSON (миллисекунды) 1С просто добавляет три нуля. Если вы получаете данные извне, миллисекунды будут отсечены при чтении в объект Дата.ЛокальнаяДата может вернуть время сервера, которое отличается от клиентского.ФорматДатыJSON.ISO. Платформа 1С поддерживает его идеально, включая автоматическую обработку смещений типа 2022-07-04T00:00:00+03:00.Таким образом, мы рассмотрели три способа решения задачи: от стандартных настроек НастройкиСериализацииJSON до ручного манипулирования строками. Выбор метода зависит от строгости требований принимающей стороны и версии платформы 1С, которую вы используете.