Как в 1С 7.7 прибавить секунды к дате и получить новое значение даты и времени?

Программист 1С v7.7
← На главную

В платформе 1С:Предприятие 8.х работа с датой и временем реализована максимально удобно: тип Дата содержит и календарное число, и время вплоть до секунд. Это позволяет выполнять простые арифметические операции, например, ТекущаяДата() + 3600 вернет время ровно через час. Однако в «семерке» (1С 7.7) ситуация иная: тип Дата хранит только число, месяц и год, а время обрабатывается отдельно как строка. Рассмотрим, как реализовать механизм работы с датами, аналогичный «восьмерке», и научим программу корректно прибавлять или отнимать секунды, учитывая переход через полночь.

Анализируем специфику хранения даты и времени в 1С 7.7

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

В сутках содержится 86 400 секунд (24 часа * 60 минут * 60 секунд). Это константа, на которой будет строиться вся наша математическая модель.

Шаг 1: Преобразование времени в секунды

Чтобы совершать операции со временем, нам нужно научиться переводить строковое представление времени (например, «14:30:15») в числовое. Разберем функцию, которая разбивает строку и вычисляет общее количество секунд с начала дня.


Функция глВремяВСекунды(СтрВремя)
    // Извлекаем часы, минуты и секунды из строки формата ЧЧ:ММ:СС
    Час = Число(Лев(СтрВремя, 2));
    Мин = Число(Сред(СтрВремя, 4, 2));
    Сек = Число(Прав(СтрВремя, 2));
    
    // Возвращаем общее количество секунд
    Возврат Час * 3600 + Мин * 60 + Сек;
КонецФункции

Эта функция станет фундаментом для наших дальнейших расчетов. Проанализируем ее работу: мы используем встроенные строковые функции Лев(), Сред() и Прав() для выделения компонентов времени, преобразуем их в число и суммируем.

Шаг 2: Преобразование секунд обратно в строковое время

После проведения расчетов нам потребуется вернуть результат в привычный для пользователя и системы формат строки. Рассмотрим пример функции обратного преобразования:


Функция глСекундыВВремя(ВсегоСекунд)
    // Ограничиваем количество секунд рамками одних суток
    СекундВСутках = 86400;
    ОстатокСекунд = ВсегоСекунд % СекундВСутках;
    
    // Если число секунд отрицательное (при вычитании), корректируем его
    Если ОстатокСекунд < 0 Тогда
        ОстатокСекунд = ОстатокСекунд + СекундВСутках;
    КонецЕсли;

    Час = Цел(ОстатокСекунд / 3600);
    Мин = Цел((ОстатокСекунд - Час * 3600) / 60);
    Сек = ОстатокСекунд - Час * 3600 - Мин * 60;
    
    // Форматируем результат с ведущими нулями
    Возврат Формат(Час, "Ч(0)2") + ":" + Формат(Мин, "Ч(0)2") + ":" + Формат(Сек, "Ч(0)2");
КонецФункции

Здесь мы применяем функцию Формат() с параметром Ч(0)2, чтобы время всегда выглядело корректно (например, «09:05:01» вместо «9:5:1»). Также мы предусмотрели обработку отрицательного остатка, что критично для операций вычитания времени.

Шаг 3: Реализация комплексной операции Сложение Даты/Времени и Секунд

Теперь объединим все знания в одну универсальную процедуру. Допустим, нам нужно к 31.12.2022 23:00:00 прибавить 7200 секунд (2 часа). Мы должны получить 01.01.2023 01:00:00.

Разберем алгоритм по шагам:

  1. Переводим текущее время в секунды.
  2. Прибавляем к ним нужное количество секунд (переменная N).
  3. Вычисляем количество полных дней, которые «поместились» в итоговой сумме секунд.
  4. Корректируем исходную дату на полученное количество дней.
  5. Получаем остаток секунд и переводим его в формат времени.

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


Процедура ПрибавитьСекундыКДатеВремя(ИсхДата, ИсхВремя, ПрибавитьСекунд, РезДата, РезВремя)
    // 1. Получаем секунды текущего дня
    СекундыНачала = глВремяВСекунды(ИсхВремя);
    
    // 2. Вычисляем общую сумму секунд
    ВсегоСекунд = СекундыНачала + ПрибавитьСекунд;
    
    // 3. Считаем количество полных дней (может быть как положительным, так и отрицательным)
    // Используем деление на 86400
    КоличествоДней = Цел(ВсегоСекунд / 86400);
    
    // 4. Получаем остаток секунд внутри суток
    ОстатокСекунд = ВсегоСекунд % 86400;
    
    // Особая обработка для отрицательных значений при переходе назад через полночь
    Если ОстатокСекунд < 0 Тогда
        КоличествоДней = КоличествоДней - 1;
    КонецЕсли;
    
    // 5. Результат
    РезДата = ИсхДата + КоличествоДней;
    РезВремя = глСекундыВВремя(ОстатокСекунд);
КонецПроцедуры

Почему это решение надежно?

Проанализируем ситуацию: почему мы не вычисляем количество секунд в году или месяце вручную? Как справедливо заметили участники обсуждения, в разных месяцах разное количество дней, существуют високосные года. Используя встроенный механизм Дата + Число, мы перекладываем всю сложную календарную арифметику на плечи движка 1С 7.7. Наша задача — только правильно выделить целое число суток из произвольного количества секунд.

Дополнительные рекомендации

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

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

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

← На главную