Разработчики платформы 1С:Предприятие часто сталкиваются с нестандартными задачами импорта данных или математических расчетов, где временные метки приходят в виде чистых чисел. Это могут быть секунды с начала суток, минуты работы оборудования или миллисекунды, зафиксированные сторонней системой учета. Стандартные методы приведения типов здесь не всегда работают напрямую, так как число и время — это принципиально разные структуры хранения.

Платформа 1С имеет строгую типизацию, поэтому попытка просто присвоить числовой переменной значение времени вызовет ошибку выполнения. Вам необходимо использовать специальные функции конструктора или методы преобразования. В этой инструкции мы рассмотрим все актуальные способы перевода числового значения в тип Время и ДатаВремя для версий платформы 8.3 и новее.

Понимание внутренней структуры хранения даты критически важно. В 1С дата — это 64-битное число с плавающей точкой, где целая часть отвечает за количество дней от 01.01.0001, а дробная — за время суток. Именно манипуляции с этой дробной частью позволяют нам конвертировать простые секунды или часы в полноценный объект времени.

Фундаментальные отличия типов данных

Прежде чем писать код, необходимо четко разграничить, с чем именно мы работаем. Тип Число в 1С может хранить любое значение: 10, 5000, 0.5. Тип Время хранит количество секунд, прошедших с начала суток (с 00:00:00). Диапазон значений времени ограничен 24 часами.

Если ваше исходное число обозначает количество секунд, прошедших с полуночи, то перевод тривиален. Однако, если число представляет собой количество минут или, что еще сложнее, миллисекунды, требуется предварительная нормализация. Ошибка в коэффициенте пересчета приведет к смещению времени на часы или даже дни.

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

💡

Всегда проверяйте диапазон входного числа. Если число секунд больше 86400 (количество секунд в сутках), функция Время() вернет время с учетом перехода через полночь, что может быть неочевидно при выводе в отчетах.

Базовый метод: функция Время()

Самый простой и надежный способ получить объект времени — использовать встроенную функцию Время(Час, Минута, Секунда). Если у вас есть число, обозначающее общее количество секунд, его нужно разложить на составляющие. Это классический алгоритмический подход, который работает стабильно на любых версиях платформы.

Для извлечения часов необходимо разделить общее количество секунд на 3600 и взять целую часть. Для минут используется остаток от деления на 3600, который затем делится на 60. Секунды — это остаток от деления на 60. В коде 1С это реализуется через операторы Цел() и Остаток().

ОбщееКоличествоСекунд = 3725; // Пример: 1 час 2 минуты 5 секунд

Часы = Цел(ОбщееКоличествоСекунд / 3600);

ОстатокПослеЧасов = ОбщееКоличествоСекунд - (Часы * 3600);

Минуты = Цел(ОстатокПослеЧасов / 60);

Секунды = ОстатокПослеЧасов - (Минуты * 60);

РезультатВремя = Время(Часы, Минуты, Секунды);

Сообщить(РезультатВремя);

Данный метод хорош своей прозрачностью. Вы видите каждый шаг преобразования. Однако, если исходное число — это дробное значение (например, секунды с миллисекундами), придется дополнительно обрабатывать дробную часть для точности.

☑️ Алгоритм ручного расчета

Выполнено: 0 / 4

Использование функции ВремяСеанса

В некоторых сценариях требуется не создать новое время с нуля, а сдвинуть текущее время сеанса на определенное числовое значение. Например, рассчитать время окончания операции, зная её длительность в минутах. Для этого идеально подходит функция ВремяСеанса() в связке с функцией ДобавитьКДате().

Функция ДобавитьКДате() универсальна. Она принимает исходную дату (или время), тип добавления (секунда, минута, час) и количество добавляемых единиц. Это избавляет разработчика от ручных вычислений остатков и делений.

Пример использования для добавления 90 минут к текущему времени:

ТекущееВремя = ВремяСеанса();

ДлительностьВМинутах = 90;

ВремяОкончания = ДобавитьКДате(ТекущееВремя, "Минута", ДлительностьВМинутах);

Если вам нужна именно дата с переходом через сутки, используйте тип Дата или ДатаВремя.

⚠️ Внимание: Функция ВремяСеанса() возвращает время компьютера пользователя (или сервера, в толстом клиенте), а не сервера 1С в явном виде, если код выполняется на клиенте. Для синхронизации используйте Сеанс.ВремяСеанса() или серверное время.

📊 Какой метод конвертации вы используете чаще?
Ручной расчет через Цел/Остаток
Функция ДобавитьКДате
Конвертация через Строку
Не работаю со временем

Конвертация миллисекунд и дробных значений

Современные системы логирования и IoT-устройства часто передают временные метки в миллисекундах (Unix time в мс или просто таймстампы). В 1С тип Время имеет точность до секунд, но тип ДатаВремя поддерживает миллисекунды. Чтобы корректно перевести число миллисекунд в время, нужно учитывать этот нюанс.

Если вы работаете с миллисекундами внутри суток, сначала разделите число на 1000, чтобы получить секунды. Дробную часть секунд можно сохранить, если вы приводите результат к типу ДатаВремя, взяв за основу текущую дату.

Алгоритм для миллисекунд:

  • 🕒 Разделите входное число на 1000 для получения секунд.
  • 📅 Выделите целую часть секунд для функции Время().
  • ⚙️ Дробную часть используйте для конструирования ДатаВремя через ДатаВремя(Дата, Время, Миллисекунды).

Пример кода для точного перевода:

Миллисекунды = 3725500; // 1 час 2 минуты 5 секунд и 500 мс

ПолныеСекунды = Цел(Миллисекунды / 1000);

ОстатокМиллисекунд = Миллисекунды - (ПолныеСекунды * 1000);

// Получаем базовое время

БазовоеВремя = Время(Цел(ПолныеСекунды/3600), Цел(Остаток(ПолныеСекунды, 3600)/60), Остаток(ПолныеСекунды, 60));

// Собираем полную дату с миллисекундами (на сегодня)

ТочноеВремя = ДатаВремя(ТекущаяДата(), БазовоеВремя, ОстатокМиллисекунд);

Почему миллисекунды важны?

В высоконагруженных системах, таких как биржевые торги или логистические трекинг-системы, разница в 100 мс может привести к потере данных или неверному порядку событий в журнале регистрации.

Специфика работы с типом ДатаВремя

Часто задача звучит как «перевести число во время», но по факту разработчику нужен полноценный объект ДатаВремя. Это особенно актуально при импорте данных из Excel или CSV, где дата и время могут быть разнесены по разным колонкам или выражены одним числом (например, количество дней от 01.01.1900, как в Excel).

В Excel дата хранится как число дней, прошедших с 1900 года. Дробная часть этого числа — это время. Чтобы перевести такое «excel-число» в 1С, нужно знать базовую дату отсчета Excel и добавить к ней полученное количество дней.

Источник данных Формат числа Метод конвертации в 1С Точность
Excel Дни (целое + дробь) ДобавитьКДате("01.01.1900", "День", Число) До секунд
Unix Timestamp Секунды (с 1970) ДобавитьКДате("01.01.1970", "Секунда", Число) До секунд
Внутренний счетчик Миллисекунды Деление на 1000 + конструктор До миллисекунд
Таймер 1С Миллисекунды Время() или ДатаВремя() Высокая

При работе с датой 01.01.1900 в 1С нужно учитывать известный баг Excel, который считает 1900 год високосным (хотя это не так). Для большинства современных дат (после 1900 года) это не влияет на расчет, но при конвертации исторических данных может возникнуть сдвиг на 1 день.

💡

При импорте дат из Excel используйте дату отсчета 30.12.1899 вместо 01.01.1900 для корректной компенсации ошибки високосного года в Excel.

Обработка ошибок и некорректных данных

В реальных базах данных числовые поля, предназначенные для хранения времени, могут содержать «мусор». Отрицательные значения, числа, превышающие количество секунд в сутках, или NULL-значения — все это может сломать алгоритм конвертации, если не предусмотрена защита.

Использование конструкции Попытка..Исключение обязательно при массовой обработке данных из внешних источников. Функция Время() выбросит исключение, если переданные ей часы больше 23 или минуты больше 59 (после ваших расчетов).

Рекомендуемый шаблон безопасного преобразования:

Функция БезопасноеВремяИзЧисла(ЧислоСекунд)

Попытка

Если ЧислоСекунд < 0 Тогда

Возврат Время(0,0,0); // Или другое значение по умолчанию

КонецЕсли;

Часы = Цел(ЧислоСекунд / 3600);

// Проверка на переполнение суток, если нужно строгое время

Если Часы >= 24 Тогда

Часы = Часы % 24;

КонецЕсли;

//.. дальнейший расчет минут и секунд..

Возврат Время(Часы, Минуты, Секунды);

Исключение

Сообщить("Ошибка конвертации: " + ОписаниеОшибки());

Возврат Неопределено;

КонецПопытки;

КонецФункции

⚠️ Внимание: Интерфейс и поведение некоторых функций могут незначительно отличаться в зависимости от режима запуска (тонкий/толстый клиент) и версии платформы. Всегда тестируйте критичные участки кода на актуальной конфигурации.

Оптимизация производительности при больших объемах

Если вам нужно перевести число во время для миллиона записей в регистре сведений, вызов функций в цикле может стать «узким горлышком». В таких случаях стоит рассмотреть возможность выполнения преобразования непосредственно в запросе к базе данных, используя виртуальные таблицы или вычисляемые поля.

Однако, язык запросов 1С имеет ограниченные возможности для сложной математики с временем. Часто эффективнее выбрать данные пачками, обработать их в буфере на стороне сервера и записать результат. Использование временных таблиц существенно ускоряет процесс по сравнению с построчной обработкой в цикле Для каждого.

Для ускорения расчетов избегайте лишних вызовов ТекущаяДата() внутри циклов. Вызовите эту функцию один раз перед циклом и сохраните результат в переменную. Разница в производительности при обработке 100 000 строк может достигать нескольких секунд, что существенно в фоновых заданиях.

Секрет скорости

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

Вопросы и ответы (FAQ)

Как перевести число 1430 (как 14:30) во время?

Если число представлено в формате ЧЧММ (например, 1430), используйте деление на 100. Часы = Цел(Число / 100), Минуты = Остаток(Число, 100). Затем передайте их в функцию Время(Часы, Минуты, 0).

Что делать, если число отрицательное?

Тип Время не поддерживает отрицательные значения. Вам нужно решить бизнес-логику: либо обнулять время, либо вычитать это значение из времени сеанса, либо использовать тип Число для хранения разницы во времени без привязки к типу Время.

Можно ли использовать форматную строку для конвертации?

Нет, функция Формат() служит только для отображения (преобразование в строку). Для преобразования Число -> Время используйте конструкторы типов или арифметические операции с датой.

Как сохранить миллисекунды при конвертации?

Тип Время не хранит миллисекунды. Используйте тип ДатаВремя. Создайте дату (например, сегодня) и добавьте к ней рассчитанное количество миллисекунд через ДобавитьКДате(.., "Миллисекунда"..).

Почему при сложении времени получается дата?

Если вы складываете тип Дата и тип Время (или число дней), результат будет типом ДатаВремя. Это нормальное поведение платформы. Если нужно только время, используйте функцию Время() для извлечения временной части из результата.