В задачах автоматизации часто возникает необходимость рассчитать продолжительность какого-либо процесса. Стандартно, при вычитании одной даты из другой в 1С, мы получаем разницу в секундах. Поскольку работа с датами в "1С:Предприятие" имеет свои особенности, это число (например, 95465) само по себе малоинформативно для пользователя. Наша задача — представить это количество секунд в наглядном и понятном виде, например: "1 день 2 часа 31 минута 5 секунд".
Рассмотрим несколько способов решения этой задачи, от простого математического разложения до использования встроенных функций платформы, а также проанализируем их преимущества и недостатки.
Наиболее надежный и гибкий метод — это создание собственной функции, которая последовательно вычисляет количество дней, часов, минут и секунд. Подобная практика для новичков отлично помогает понять логику работы с целочисленным делением и получением остатка от деления. Этот подход дает полный контроль над форматом вывода.
Разберем логику по шагам:
Цел(), чтобы отбросить дробную часть.%.Цел().%, но уже с делителем 3600.Посмотрим на практическую реализацию этого алгоритма. Ниже представлена функция, которая полностью решает поставленную задачу. Чтобы понять, как красиво вывести результат в интерфейс, полезно знать, что такое форматированный документ и как с ним работать.
// Функция для преобразования секунд в форматированную строку (Дни, Часы, Минуты, Секунды)
//
// Параметры:
// ВремяВСек - Число - общее количество секунд для преобразования.
//
// Возвращаемое значение:
// Строка - отформатированное представление времени.
//
Функция РазложитьДату(ВремяВСек) Экспорт
// Определяем количество секунд в минуте, часе и дне
СекундВМинуте = 60;
СекундВЧасе = 60 * СекундВМинуте;
СекундВДне = 24 * СекундВЧасе;
// Вычисляем количество полных дней
Дни = Цел(ВремяВСек / СекундВДне);
ОстатокСекунд = ВремяВСек % СекундВДне;
// Из остатка вычисляем количество полных часов
Часы = Цел(ОстатокСекунд / СекундВЧасе);
ОстатокСекунд = ОстатокСекунд % СекундВЧасе;
// Из нового остатка вычисляем количество полных минут
Минуты = Цел(ОстатокСекунд / СекундВМинуте);
// Все, что осталось - это секунды
Секунды = ОстатокСекунд % СекундВМинуте;
// Формируем результирующую строку
Возврат Формат(Дни, "ЧГ=0") + " дн. "
+ Формат(Часы, "ЧГ=0") + " час. "
+ Формат(Минуты, "ЧГ=0") + " мин. "
+ Формат(Секунды, "ЧГ=0") + " сек.";
КонецФункции // РазложитьДату()
Пример использования:
Допустим, нам нужно узнать, сколько времени прошло между двумя датами.
ДатаНачала = ТекущаяДата() - 3600*26; // Примерно 1 день и 2 часа назад
ДатаОкончания = ТекущаяДата();
РазницаВСекундах = ДатаОкончания - ДатаНачала; // Получаем, например, 93600 секунд
// Вызываем нашу функцию
ПредставлениеВремени = РазложитьДату(РазницаВСекундах);
// В переменной ПредставлениеВремени будет строка: "1 дн. 2 час. 0 мин. 0 сек."
Сообщить(ПредставлениеВремени);
Этот метод является самым предпочтительным, так как он прозрачен, легко читается и может быть модифицирован под любые нужды, например, для добавления правильных склонений ("день", "дня", "дней").
Существует и другой подход к реализации той же логики. Вместо использования оператора остатка от деления %, можно на каждом шаге вычитать из общего количества секунд уже посчитанную величину. Такая разработка с учетом показателей времени часто кажется более интуитивной.
Проанализируем этот вариант:
Функция ПредставлениеПериодаВСекундах(Секунд)
Значение = Секунд;
Результат = "";
// Вычисляем дни
Дней = Цел(Значение / 86400);
Если Дней > 0 Тогда
Результат = Результат + Дней + " дн. ";
Значение = Значение - Дней * 86400; // Уменьшаем общее количество секунд
КонецЕсли;
// Вычисляем часы
Часов = Цел(Значение / 3600);
Если Часов > 0 Тогда
Результат = Результат + Часов + " ч. ";
Значение = Значение - Часов * 3600; // Уменьшаем остаток
КонецЕсли;
// Вычисляем минуты
Минут = Цел(Значение / 60);
Если Минут > 0 Тогда
Результат = Результат + Минут + " мин. ";
Значение = Значение - Минут * 60;
КонецЕсли;
// Оставшееся значение - секунды
Если Значение > 0 Тогда
Результат = Результат + Значение + " сек.";
КонецЕсли;
Возврат СокрЛП(Результат); // Убираем лишние пробелы в начале и конце
КонецФункции
Ключевое отличие этого способа в том, что он формирует строку динамически. Если при объединении данных вы столкнетесь с проблемами производительности, рекомендуем изучить быстрое объединение строк в одну. В данном примере, если количество дней или часов равно нулю, они просто не будут добавлены в итоговую строку.
В платформе 1С есть мощная функция Формат(), которую можно нестандартно применить для нашей задачи. Идея заключается в том, чтобы прибавить наше количество секунд к начальной дате (01.01.0001 00:00:00) и затем отформатировать полученную дату.
ВсегоСекунд = 95465; // Наш пример: 1 день, 2 часа, 31 минута, 5 секунд
// Прибавляем секунды к "нулевой" дате
ПолученнаяДата = Дата('00010101') + ВсегоСекунд;
// Форматируем результат
СтрокаДаты = Формат(ПолученнаяДата, "ДФ='dd.MM.yyyy HH:mm:ss'");
// Результат будет: "02.01.0001 02:31:05"
Сообщить(СтрокаДаты);
Важные моменты и недостатки этого подхода:
Вывод: данный способ можно рассматривать как академический пример возможностей платформы, но для основной задачи он менее удобен и надежен, чем создание собственной функции.
Мы рассмотрели три разных способа преобразования секунд в человекочитаемый формат. Наиболее рекомендуемым является первый метод — создание функции, основанной на математическом разложении. Он обеспечивает полный контроль, предсказуемость результата и высокую производительность.
Второй метод является его логической альтернативой и может быть полезен, если требуется динамическое формирование строки без нулевых значений. Третий метод с функцией Формат() применяется на практике редко из-за своих ограничений при работе с календарными датами.