Как преобразовать секунды в формат ЧЧ:мм, если часов больше 24

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

В разработке на платформе 1С:Предприятие часто возникает задача отображения временных интервалов. Это может быть время работы оборудования, общая длительность звонков или суммарное время выполнения задач. Стандартный подход с использованием типа Дата и форматной строки ДФ=ЧЧ:мм отлично работает, пока интервал не превышает одни сутки (86 400 секунд). Как только время переваливает за этот порог, встроенные механизмы начинают вести себя не так, как ожидает пользователь: вместо условных 30 часов мы видим 06:00, так как система отбрасывает полные дни и оставляет только время внутри текущих суток.

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

Почему стандартный метод выдает неверный результат?

Разберем пример из обсуждения. При попытке выполнить следующий код:


лкСекунды = 567000;
Сообщить(Формат(Дата(1,1,1) + лкСекунды, "ДФ=ЧЧ:мм"));

Мы получаем результат 13:30. Это происходит потому, что тип Дата в 1С — это всегда конкретный момент во времени, а не длительность. Прибавляя секунды к пустой дате 01.01.0001, мы получаем новую дату. Система видит, что прошло несколько полных дней, и при использовании формата ЧЧ:мм просто показывает время последнего дня. Чтобы вывести общее накопленное время, нам придется реализовать алгоритм «вручную».

Математический расчет интервала

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

  1. Часы: Чтобы узнать полное количество часов, мы делим общее число секунд на 3600 (количество секунд в одном часе) и берем целую часть.
  2. Минуты: Нам нужно получить остаток от деления на 3600 (это будут секунды, не вошедшие в полные часы) и разделить его на 60.

Посмотрим на пример кода, реализующий эту логику:


лкСекунды = 567000;
Часы = Цел(лкСекунды / 3600);
Минуты = Цел((лкСекунды % 3600) / 60);

Здесь оператор % возвращает остаток от деления. Например, если у нас 3700 секунд, то 3700 % 3600 вернет 100 секунд. Далее 100 / 60 даст 1.66, а функция Цел() отсечет дробную часть, оставив 1 минуту.

Сборка итоговой строки и проблема лидирующих нулей

Просто соединить полученные числа через двоеточие недостаточно. Если минут окажется меньше 10, мы получим некрасивую строку вида 157:5 вместо 157:05. Рассмотрим подробнее, как решить эту задачу с помощью функции СтрШаблон или Формат.

Для корректного вывода минут мы должны применить форматирование ЧЦ=2; ЧВН=. Параметр ЧЦ=2 указывает на общее количество знаков, а ЧВН= (Число С Ведущими Нулями) заставляет систему дописывать ноль слева, если число состоит из одной цифры.

Разберем итоговый вариант функции:


Функция ПреобразоватьСекундыВТекст(Знач лкСекунды) Экспорт
    Часы = Цел(лкСекунды / 3600);
    Минуты = Цел((лкСекунды % 3600) / 60);
    
    // Форматируем минуты, чтобы всегда было 2 знака
    ТекстМинуты = Формат(Минуты, "ЧЦ=2; ЧВН=");
    
    Возврат СтрШаблон("%1:%2", СокрЛП(Часы), ТекстМинуты);
КонецФункции

Работа с отрицательными интервалами

В реальных задачах, например, при расчете переработок или отклонений от графика, количество секунд может быть отрицательным. Если просто передать отрицательное число в наш алгоритм, функции Цел и % могут выдать неожиданный результат. Проанализируем ситуацию: как правильно обработать минус?

Рекомендуется сначала определить знак, сохранить его, а расчеты производить с абсолютным значением (модулем) числа. Посмотрим на расширенный пример кода:


Знак = ?(лкСекунды < 0, "-", "");
АбсСекунды = Макс(лкСекунды, -лкСекунды);

Часы = Цел(АбсСекунды / 3600);
Минуты = Цел((АбсСекунды % 3600) / 60);

Результат = Знак + СокрЛП(Часы) + ":" + Формат(Минуты, "ЧЦ=2; ЧВН=");

Нюансы округления: почему важно использовать Цел()

В обсуждении на форуме упоминалась функция Окр(). Важно понимать, что в задачах учета времени математическое округление может быть вредным. Например, если у нас есть 59 секунд, это еще не полная минута. Функция Окр(59/60, 0) превратит это в 1 минуту, что исказит отчетность. Поэтому мы всегда используем Цел(), чтобы учитывать только фактически завершенные временные отрезки.

Применение в Системе компоновки данных (СКД)

Если вам нужно вывести время в формате ЧЧ:мм в отчете, не обязательно писать код в модуле. Можно воспользоваться «Вычисляемыми полями» в СКД. Выясним, как составить выражение для такого поля:

В колонке «Выражение» для поля Длительность напишите:

Строка(Цел(Секунды / 3600)) + ":" + Формат((Секунды % 3600) / 60, "ЧЦ=2; ЧВН=")

Однако помните, что такое поле станет строковым, и вы не сможете легко вычислить по нему «Итоги» (сумму) в подвале отчета. Поэтому правильной стратегией будет хранение в ресурсах суммы секунд, а форматирование — только на уровне представления или в отдельном вычисляемом поле для вывода.

Дополнительные возможности: учет дней и секунд

Если временной интервал очень велик, пользователю может быть сложно воспринимать значение вроде 157:30. В таких случаях мы можем выделить количество полных суток. Разберем по шагам, как расширить наш алгоритм:

  1. Вычисляем количество суток: Сутки = Цел(Секунды / 86400).
  2. Вычисляем остаток секунд после выделения суток: ОстатокСекунд = Секунды % 86400.
  3. Из остатка получаем часы и минуты по описанному выше алгоритму.

Это позволит сформировать строку вида 6 дн. 13 ч. 30 мин., что значительно повышает читаемость отчетов в крупных информационных системах.

Подведем итог: для преобразования секунд в формат, поддерживающий более 24 часов, мы отказываемся от стандартного типа Дата в пользу арифметических вычислений. Использование связки функций Цел(), % и правильной форматной строки для минут ЧЦ=2; ЧВН= гарантирует точность и корректное визуальное представление данных.

← На главную