Как получить время в часах, минутах и секундах из разности дат в 1С?

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

При разработке в среде 1С:Предприятие 8.3 часто возникает задача вычисления разницы между двумя датами и вывода полученного интервала в удобном для пользователя текстовом формате (например, «49 час. 23 мин. 12 сек.»). Это критически важно для систем учета рабочего времени, расчетов трудозатрат программистов, фиксации времени доставки или простоя оборудования. В этой статье мы подробно разберем, как решить эту задачу, избежав типичных ошибок переполнения, рассмотрим использование готовых системных функций и коснемся правильного проектирования бизнес-логики.

Метод 1. Прямой математический расчет (Классический подход)

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

Рассмотрим по шагам формулу, предложенную в начале обсуждения, и оптимизируем её. В исходном сообщении автор использовал громоздкие вычитания. Мы можем существенно упростить код, применив оператор остатка от деления %:


// Исходные данные
ДатаНачала = '20190101122431'; // 01.01.2019 12:24:31
ДатаОкончания = '20190102090347'; // 02.01.2019 09:03:47
РазностьВСекундах = ДатаОкончания - ДатаНачала;

// Выполняем математический расчет
Часов = Цел(РазностьВСекундах / 3600);
Минут = Цел((РазностьВСекундах % 3600) / 60);
Секунд = РазностьВСекундах % 60;

// Формируем результирующую строку
ВремяФормат = "" + Часов + " час. " + Минут + " мин. " + Секунд + " сек.";

Этот алгоритм работает безупречно при любой разности дат, будь то 5 минут или 5000 часов. В нем нет ограничений на переполнение разрядности времени, так как мы не привязываемся к структуре календаря.

Метод 2. Использование объекта Дата и скрытая ловушка

Некоторые разработчики пытаются использовать свойства объекта Дата для получения нужных составляющих. Идея заключается в том, чтобы прибавить полученную разность секунд к «пустой» дате (началу времен) и затем получить часы, минуты и секунды встроенными функциями платформы:


// Получаем секунды
ВремяСек = ДатаОкончания - ДатаНачала;
_Дата = Дата(1, 1, 1) + ВремяСек;

// Пробуем получить представление
ВремяФормат = "" + Час(_Дата) + " час. " + Минута(_Дата) + " мин. " + Секунда(_Дата) + " сек.";

В чем главная проблема этого метода? Он работает корректно только в том случае, если разность дат не превышает 24 часа. Если разность составит, например, 26 часов, то функция Час(_Дата) вернет 2 (так как время перейдет на следующий день — 2 января 0001 года).

В Сообщении 10 форума была предложена формула для обхода этого лимита:

ВремяФормат = "" + ((День(_Дата)-1) * 24 + Час(_Дата)) + " час. " + ...

Проанализируем эту формулу детально. На первый взгляд она решает проблему: мы берем день месяца, вычитаем единицу (так как отсчет дней начинается с 1 января), умножаем на 24 часа и прибавляем часы текущего дня. Однако здесь кроется критическая ошибка, которая проявится при длительных интервалах!

Функция День(_Дата) возвращает день месяца (число от 1 до 31). Как только разность дат превысит 31 день, дата «перевалит» на февраль (01.02.0001). При этом функция День(_Дата) снова вернет 1! В результате расчетов мы безвозвратно потеряем 31 день (744 часа). Поэтому использовать объект Дата для расчета произвольных интервалов времени напрямую через свойства дней и часов категорически не рекомендуется.

Метод 3. Использование готовых механизмов БСП

Если вы работаете в любой современной типовой конфигурации 1С (такой как УТ, ERP, КА, ЗУП, УНФ), вам не нужно писать собственные алгоритмы для форматирования интервалов. В составе Библиотеки стандартных подсистем (БСП) уже есть готовые функции, которые сделают всю работу за вас и даже красиво склоняют слова.

Рассмотрим обращение к общему модулю БСП НапоминанияПользователяКлиентСервер. Функция ПредставлениеВремени идеально решает нашу задачу:


РазностьВСекундах = ДатаОкончания - ДатаНачала;

// Параметры: Секунды, ВыводитьДни, ВыводитьСекунды
СтрокаВремени = НапоминанияПользователяКлиентСервер.ПредставлениеВремени(РазностьВСекундах, Истина, Истина);
// Результат будет выглядеть так: "1 день 20 часов 39 минут 16 секунд"

Использование БСП делает ваш код чище, надежнее и гарантирует, что интерфейс программы будет выглядеть профессионально.

Метод 4. Как решать задачу в отчетах (СКД)

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

Проанализируем правильный подход:

  1. В запросе СКД вычислите разность дат в секундах с помощью стандартной функции: РАЗНОСТЬДАТ(ДатаНачала, ДатаОкончания, СЕКУНДА).
  2. Добавьте это поле в ресурсы СКД, чтобы его можно было суммировать по группировкам.
  3. Вкладка «Наборы данных» -> выберите ваше поле -> найдите колонку «Выражение представления».
  4. Пропишите там вызов экспортной функции вашего общего модуля, передав туда значение поля. Например: МойОбщийМодуль.ФорматироватьСекунды(ВычисляемоеПоле).

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

Метод 5. Учет бизнес-логики: Реальное рабочее время и графики

Как справедливо заметили участники обсуждения на форуме, простое математическое вычитание ДатаОкончания - ДатаНачала в реальных задачах автоматизации учета практически никогда не отражает действительность.

Представьте ситуацию: программист взял задачу в работу в пятницу в 17:00, а закрыл её в понедельник в 10:00. Физическая разница составляет 65 часов. Но работал ли он все эти 65 часов? Конечно нет. По стандартному рабочему графику (с 9:00 до 18:00, за вычетом выходных) чистое время работы составило всего 2 часа (1 час в пятницу и 1 час в понедельник).

Чтобы реализовать корректный учет рабочего времени в 1С, вам потребуется задействовать следующие механизмы:

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

← На главную