Как в 1С рассчитать разницу между двумя датами в часах?

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

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

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

Способ 1: Арифметическое вычисление в коде 1С

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

Чтобы получить количество часов, нам нужно разделить полученную разницу в секундах на 3600 (поскольку в одном часе 60 минут, а в каждой минуте 60 секунд, итого 60 * 60 = 3600).

Рассмотрим по шагам:

  1. Определим две переменные типа Дата: ДатаНачала и ДатаОкончания.
  2. Вычтем из конечной даты начальную.
  3. Разделим полученный результат на 3600.

Посмотрим на пример кода:


Перем ДатаНачала, ДатаОкончания, РазницаВЧасах;

// Задаем начальную и конечную дату и время
ДатаНачала = '20230920100000'; // 20 сентября 2023 г. 10:00:00
ДатаОкончания = '20230920153000'; // 20 сентября 2023 г. 15:30:00

// Вычисляем разницу в секундах и переводим в часы
РазницаВЧасах = (ДатаОкончания - ДатаНачала) / 3600;

// Выводим результат
Сообщить("Разница в часах: " + РазницаВЧасах); // Результат: 5.5

Как видно из примера, результат получается дробным. Это очень удобно, когда нужна максимальная точность. Если же по условиям задачи требуется получить только количество целых часов, можно воспользоваться функциями округления:

Пример с округлением в меньшую сторону (получение полных часов):


КоличествоПолныхЧасов = Цел((ДатаОкончания - ДатаНачала) / 3600);
Сообщить("Количество полных часов: " + КоличествоПолныхЧасов); // Результат: 5

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

Способ 2: Использование функции РАЗНОСТЬДАТ() в запросе

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

Для этой цели в языке запросов 1С существует специальная функция РАЗНОСТЬДАТ().

Синтаксис функции:

РАЗНОСТЬДАТ(<Дата1>, <Дата2>, <ТипРазности>)

Важный момент: функция РАЗНОСТЬДАТ() возвращает количество полных интервалов. Например, если разница составляет 5 часов 59 минут, РАЗНОСТЬДАТ(..., ..., ЧАС) вернет 5. Она работает аналогично функции Цел() из первого способа.

Посмотрим на простой пример запроса:


Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |    РАЗНОСТЬДАТ(&ДатаНачала, &ДатаОкончания, ЧАС) КАК КоличествоЧасов";

Запрос.УстановитьПараметр("ДатаНачала", '20230920100000');
Запрос.УстановитьПараметр("ДатаОкончания", '20230920153000');

Результат = Запрос.Выполнить().Выгрузить();
Сообщить("Количество полных часов (из запроса): " + Результат[0].КоличествоЧасов); // Результат: 5

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

Расширенный пример: расчет рабочих часов

Иногда задача усложняется: нужно посчитать не просто астрономические часы, а рабочие, то есть с учетом графика работы.

Ниже приведен пример функции, которая рассчитывает количество часов в заданном интервале, но только в пределах "рабочего дня", например, с 8:00 до 17:00. Этот код иллюстрирует, как базовые методы можно адаптировать под сложную бизнес-логику.


Функция КолЧасов(ДатаН, ДатаК) Экспорт
    
    Перем Кол;
    
    ДН = НачалоДня(ДатаН);
    ДК = НачалоДня(ДатаК);
    
    // Если интервал в пределах одного дня
    Если ДН = ДК Тогда
        // Ограничиваем интервал рабочими часами (с 8 до 17)
        ДатаН1 = Макс(ДатаН, ДН + 8*3600);
        ДатаК1 = Мин(ДатаК, ДК + 17*3600);
        
        Если ДатаН1 < ДатаК1 Тогда
            Кол = (ДатаК1 - ДатаН1)/3600;
        Иначе
            Кол = 0;
        КонецЕсли;
    Иначе // Если интервал охватывает несколько дней
        Кол = 0;
        
        // Часы в первый день
        ДатаН1 = Макс(ДатаН, ДН + 8*3600);
        ДатаК1 = ДН + 17*3600;
        Если ДатаН1 < ДатаК1 Тогда
            Кол = Кол + (ДатаК1 - ДатаН1)/3600;
        КонецЕсли;
        
        // Часы в последний день
        ДатаН1 = ДК + 8*3600;
        ДатаК1 = Мин(ДатаК, ДК + 17*3600);
        Если ДатаН1 < ДатаК1 Тогда
            Кол = Кол + (ДатаК1 - ДатаН1)/3600;
        КонецЕсли;
        
        // Часы за полные дни между начальной и конечной датами
        Д = ДН + 24*3600;
        Пока Д < ДК Цикл
            Кол = Кол + 9; // 9 рабочих часов в день (17 - 8)
            Д = Д + 24*3600;
        КонецЦикла;
        
    КонецЕсли;
    
    Возврат Кол;
    
КонецФункции

Проанализируем этот алгоритм:

  1. Функция проверяет, находятся ли начальная и конечная даты в пределах одного дня.
  2. Если да: она "обрезает" интервал, чтобы он не выходил за рамки с 8:00 до 17:00, и вычисляет длительность.
  3. Если нет: она отдельно считает рабочие часы для первого дня, для последнего дня и добавляет по 9 часов за каждый полный рабочий день между ними.

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

Подведем итог:

← На главную