В современной разработке интеграций с веб-сервисами, API и внешними базами данных часто возникает задача передачи времени в формате Unix Timestamp. Под этим термином обычно подразумевается количество миллисекунд, прошедших с полуночи (00:00:00 UTC) 1 января 1970 года. Однако платформа 1С:Предприятие 7.7 создавалась в то время, когда работа с миллисекундами не была штатной потребностью, поэтому встроенных функций для получения такого значения «из коробки» не существует.
В данной статье мы подробно разберем, как вычислить Timestamp, имея на входе семь составляющих: год, месяц, день, час, минута, секунда и миллисекунда. Мы проанализируем несколько подходов — от чистого математического расчета до использования внешних сценариев.
Самый прямой путь — это использование арифметики дат, которая в 1С 7.7 работает достаточно надежно. Напомним, что при вычитании одной даты из другой платформа возвращает количество дней. Разберем этот алгоритм по шагам.
Шаг 1: Определение разницы в днях. Для начала нам нужно понять, сколько полных суток прошло с начала «эпохи Unix» до нашей целевой даты. Рассмотрим пример:
ДатаНачалаЭпохи = '01.01.1970';
КоличествоДней = ЦелеваяДата - ДатаНачалаЭпохи;
Шаг 2: Перевод дней в секунды. В сутках ровно 86 400 секунд (для целей Unix Timestamp корректировочные секунды обычно не учитываются, каждый день считается равным 86 400 секундам). Умножаем полученные дни на это число.
Шаг 3: Добавление времени текущего дня. Нам необходимо вычислить, сколько секунд прошло с начала текущего дня до момента события. Проанализируем, как это сделать с помощью функции СекундыОтНачалаДня или простого суммирования:
СекундыВремени = Час * 3600 + Минута * 60 + Секунда;
ОбщееКоличествоСекунд = (КоличествоДней * 86400) + СекундыВремени;
Шаг 4: Учет часового пояса (UTC). Это критически важный момент. 1С 7.7 работает с локальным временем компьютера. Unix Timestamp по стандарту должен быть в UTC. Если ваш сервер находится, например, в часовом поясе MSK (UTC+3), вам необходимо вычесть эти 3 часа из общего количества секунд.
Шаг 5: Перевод в миллисекунды. Итоговое число секунд умножаем на 1000 и добавляем имеющиеся миллисекунды.
Рассмотрим итоговую функцию для расчета:
Функция ПолучитьTimestamp(ДатаВхода, Час, Мин, Сек, Мс, СмещениеПоясаЧасов = 3)
ДнейСНачалаЭпохи = ДатаВхода - '01.01.1970';
ВсегоСекунд = (ДнейСНачалаЭпохи * 86400) + (Час * 3600) + (Мин * 60) + Сек;
// Корректируем на часовой пояс
ВсегоСекунд = ВсегоСекунд - (СмещениеПоясаЧасов * 3600);
// В 1С 7.7 большие числа могут терять точность, поэтому для
// миллисекундного Timestamp лучше использовать строковую сборку
СтрокаTimestamp = Строка(ВсегоСекунд) + Формат(Мс, "Ч(0)3");
Возврат СтрокаTimestamp;
КонецФункции
Если нам нужна максимальная точность и автоматическая обработка всех нюансов календаря, мы можем воспользоваться объектом MSScriptControl.ScriptControl. В языке JavaScript (JScript) объект Date возвращает Timestamp одной простой командой getTime().
Проанализируем ситуацию: этот метод хорош тем, что JScript корректно обрабатывает переходы на летнее время (если это актуально для исторических данных) и другие календарные сложности. Выясним, как реализовать это в коде 1С 7.7:
Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
Скрипт.Language = "JScript";
// Передаем параметры: год, месяц (в JS месяцы от 0 до 11), день, час, мин, сек, мс
// Внимание: в JScript месяцы начинаются с нуля!
КодJS = "new Date(" + Год + "," + (Месяц - 1) + "," + День + "," + Час + "," + Минута + "," + Секунда + "," + Мс + ").getTime()";
Timestamp = Скрипт.Eval(КодJS);
Важный нюанс: Стандартный вызов new Date(...) в JS создаст объект в локальном времени. Чтобы получить честный UTC Timestamp, убедитесь, что вы либо передаете время уже в UTC, либо используете метод Date.UTC() внутри скрипта.
Разберем серьезную техническую особенность 1С 7.7. Тип Число в этой версии платформы имеет ограничение по разрядности. Timestamp в миллисекундах для 2023-2024 годов — это число, состоящее из 13 знаков (например, 1704067200000). При выполнении математических операций с такими числами программисты часто сталкиваются с округлением или переполнением.
Рекомендация: Для надежного хранения и передачи Timestamp в 1С 7.7 используйте тип Строка. При выполнении расчетов (как в Методе 1) старайтесь оперировать секундами, а миллисекунды «приклеивать» в самом конце как текстовые символы.
Иногда под Timestamp ошибочно понимают строковое представление даты в формате ISO 8601 (например, 2023-10-05T12:00:00.000Z). Если ваша задача — подготовить именно такую строку, воспользуемся функцией Формат для обеспечения ведущих нулей (чтобы вместо «2» получить «02»).
Посмотрим на пример правильного формирования такой строки:
Функция ДатаВISO8601(ДатаВхода, Час, Мин, Сек, Мс)
СтрГод = ДатаГод(ДатаВхода);
СтрМес = Формат(ДатаМесяц(ДатаВхода), "Ч(0)2");
СтрДень = Формат(ДатаЧисло(ДатаВхода), "Ч(0)2");
СтрЧас = Формат(Час, "Ч(0)2");
СтрМин = Формат(Мин, "Ч(0)2");
СтрСек = Формат(Сек, "Ч(0)2");
СтрМс = Формат(Мс, "Ч(0)3");
Возврат "" + СтрГод + "-" + СтрМес + "-" + СтрДень + "T" + СтрЧас + ":" + СтрМин + ":" + СтрСек + "." + СтрМс + "Z";
КонецФункции
Мы рассмотрели несколько способов решения задачи. Выясним, какой из них выбрать:
SELECT DATEDIFF_BIG(ms, '1970-01-01', GETUTCDATE()).Помните о «Проблеме 2038 года»: 32-битные системы перестанут корректно обрабатывать Timestamp в секундах, когда их количество превысит лимит. Однако, используя строковое представление и 64-битные аналоги расчетов, мы обеспечиваем работоспособность наших решений на долгие годы вперед.