К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как сложить дату и время в 1С

Как сложить дату и время в 1С: прибавление секунд, дней и месяцев к дате, функции ДобавитьМесяц, работа с типом Дата, примеры кода и типичные ошибки.

В языке 1С нет отдельной арифметики «дата плюс дата», но сложение даты и времени решается стандартными средствами: оператором прибавления секунд, функцией ДобавитьМесяц и преобразованием строк в тип Дата. Понимание того, как платформа хранит дату, избавляет от большинства ошибок при расчётах сроков, графиков и периодов.

Тип Дата в 1С всегда содержит и дату, и время с точностью до секунды. Это значит, что «сложить дату и время» обычно означает одну из трёх задач: прибавить к дате определённое количество времени, объединить отдельно хранящиеся дату и время в одно значение или вычислить разницу между двумя моментами. Ниже разобраны все три сценария с примерами кода.

Как 1С хранит дату и время

Значение типа Дата в платформе — это единая величина, включающая календарную дату и время суток. Даже если вы видите в форме только «12.05.2026», внутри хранится и время, по умолчанию 00:00:00. Поэтому сравнение двух дат оператором «=» может неожиданно не сработать, если у одной из них время отлично от полуночи.

При арифметических операциях с датой единица измерения — секунда. Выражение Дата1 + 60 прибавляет одну минуту, Дата1 + 86400 — одни сутки. Вычитание двух дат (Дата2 - Дата1) возвращает разницу в секундах, что удобно для расчёта длительности.

Прибавление секунд, минут, часов и дней к дате

Самый простой способ сдвинуть дату — прибавить нужное количество секунд. Чтобы не держать в голове пересчёт, удобно умножать: 60 секунд в минуте, 3600 в часе, 86400 в сутках.

ИсходнаяДата = ТекущаяДата();

// Прибавить 15 минут

Через15Минут = ИсходнаяДата + 15 * 60;

// Прибавить 3 часа

Через3Часа = ИсходнаяДата + 3 * 3600;

// Прибавить 7 дней

ЧерезНеделю = ИсходнаяДата + 7 * 86400;

Такой подход корректно переносит результат через границы суток, месяцев и лет: платформа сама пересчитает календарную составляющую. Вычитание работает симметрично — ИсходнаяДата - 86400 вернёт тот же момент сутки назад.

Прибавление месяцев и лет: функция ДобавитьМесяц

Прибавлять месяцы через секунды нельзя: месяцы имеют разную длину, и «30 дней» не равно «одному месяцу». Для этого в языке есть функция ДобавитьМесяц(Дата, ЧислоМесяцев). Отрицательный второй аргумент отнимает месяцы.

// Прибавить 3 месяца

НоваяДата = ДобавитьМесяц(ИсходнаяДата, 3);

// Отнять 1 год (12 месяцев)

ГодНазад = ДобавитьМесяц(ИсходнаяДата, -12);

Важная особенность: если исходный день не существует в целевом месяце (например, 31 января плюс один месяц), функция вернёт последний день целевого месяца — в данном случае конец февраля. Учитывайте это при расчётах платежей и договорных сроков, где «тот же день через месяц» и «конец месяца» могут иметь разные юридические последствия.

Как объединить отдельные дату и время в одно значение

Частая практическая задача: дата хранится в одном реквизите (например, «ДатаОтгрузки»), а время — в другом («ВремяОтгрузки» в виде строки или числа). Сложить их напрямую оператором «+» нельзя — нужно собрать итоговое значение через функцию Дата() либо прибавить время к началу дня.

// Вариант 1: через функцию Дата с явными компонентами

ИтоговаяДата = Дата(Год(ДатаОтгрузки), Месяц(ДатаОтгрузки), День(ДатаОтгрузки),

ЧасВремя, МинутаВремя, 0);

// Вариант 2: прибавить секунды к началу дня

СекундСПолуночи = ЧасВремя 3600 + МинутаВремя 60;

ИтоговаяДата = НачалоДня(ДатаОтгрузки) + СекундСПолуночи;

Второй вариант короче и надёжнее, если время задано числом часов и минут. Если время хранится строкой вида «14:30», её сначала нужно разобрать: найти позицию двоеточия функцией СтрНайти(), извлечь части через Лев()/Сред() и преобразовать в числа функцией Число().

Как объединить дату и время из двух полей
  1. 1
    Проверьте, в каком виде хранится время: число часов/минут или строка
  2. 2
    Если строка — разберите её на часы и минуты и преобразуйте в числа
  3. 3
    Возьмите НачалоДня() от даты, чтобы отсечь случайное время
  4. 4
    Прибавьте часы <em> 3600 + минуты </em> 60 + секунды
  5. 5
    Проверьте результат выводом в формате с временем: Формат(Результат, "ДЛФ=DT")

Вычисление разницы между датами

Обратная задача — узнать, сколько времени прошло между двумя моментами. Вычитание дат возвращает секунды, которые затем переводятся в нужные единицы делением.

РазницаСек = ДатаОкончания - ДатаНачала;

ЧасовМежду = Цел(РазницаСек / 3600);

ДнейМежду = Цел(РазницаСек / 86400);

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

Способы арифметики с датами

Оператор + (секунды)

Подходит для минут, часов и точных интервалов. Ограничение: не подходит для месяцев и лет из-за разной длины месяцев.

ДобавитьМесяц()

Правильный способ прибавлять месяцы и годы. Учитывайте переход 31-го числа на последний день короткого месяца.

РАЗНОСТЬДАТ() в запросе

Оптимально для вычисления разницы между датами прямо в запросе без выборки данных в код.

Работа с датами в запросах

В языке запросов доступны свои инструменты: ДОБАВИТЬКДАТЕ(Дата, Тип, Количество) для сдвига даты и РАЗНОСТЬДАТ(Дата1, Дата2, Тип) для разницы. Тип задаётся ключевым словом: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, ГОД.

ВЫБРАТЬ

ДОБАВИТЬКДАТЕ(Заказ.ДатаОтгрузки, ДЕНЬ, 3) КАК ПлановаяДата,

РАЗНОСТЬДАТ(Заказ.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейСЗаказа

ИЗ

Документ.ЗаказПокупателя КАК Заказ

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

Типичные ошибки и проверка результата

Самая частая проблема — сравнение дат «в лоб», когда одна дата содержит время, а другая нет. Условие ДатаДокумента = ДатаОтбора не выполнится, если у документа время 10:25:00, а у отбора 00:00:00. Решение — сравнивать через НачалоДня() или использовать диапазон от начала до конца дня.

Вторая группа ошибок связана с пустыми датами. Пустая дата в 1С — это 01.01.0001 00:00:00, и арифметика с ней даст технически корректный, но бессмысленный результат. Перед расчётами проверяйте заполненность через ЗначениеЗаполнено().

Типичные ошибки
01
Прибавление месяца как 30 * 86400 — результат смещается на несколько дней за год
02
Сравнение дат с временем и без через «=» — условие не срабатывает, хотя день совпадает
03
Сложение даты и строки со временем оператором «+» — ошибка типов, строку нужно разбирать на числа
04
Игнорирование пустой даты 01.01.0001 — расчёт срока даёт огромные отрицательные или положительные значения
05
Использование ТекущаяДата() на сервере там, где важно время клиента в другом часовом поясе

Часовые пояса — отдельный источник расхождений в распределённых базах. Функция ТекущаяДата() возвращает время сервера при выполнении на сервере. Если пользователи работают в разных поясах, для унификации используют универсальное время или явно фиксируют пояс сеанса.

Контрольные точки

Как проверить результат

Вывод итоговой даты
Норма

Формат(Результат, "ДЛФ=DT") показывает ожидаемые дату и время

Тревожный признак

Время 00:00:00 там, где должны быть часы и минуты — время потеряно при сборке

Переход через границу месяца
Норма

31.01 + 1 месяц даёт конец февраля — ожидаемое поведение ДобавитьМесяц

Тревожный признак

Результат попадает в март — вероятно, месяц прибавляли секундами

Сравнение дат
Норма

Сравнение через НачалоДня() срабатывает для одного календарного дня

Тревожный признак

Одинаковые на вид даты не равны — у одной есть время

Итог

Что важно запомнить

Дата в 1С — это дата плюс время с точностью до секунды. Секунды, минуты, часы и дни прибавляйте оператором «+», месяцы и годы — функцией ДобавитьМесяц, в запросах используйте ДОБАВИТЬКДАТЕ и РАЗНОСТЬДАТ. Перед расчётами проверяйте заполненность дат и не забывайте про время при сравнениях.

Частые вопросы

Как прибавить к дате один рабочий день, пропуская выходные?

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

Чем отличается ТекущаяДата() от ТекущаяДатаСеанса()?

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

Можно ли сложить две даты между собой?

Нет, операция «дата + дата» не имеет смысла и платформой не поддерживается. Складывать можно дату и число секунд. Если нужно объединить дату из одного значения и время из другого, берите НачалоДня() первой даты и прибавляйте секунды, прошедшие с начала дня второй.

Как получить из даты только время?

Вычтите из даты её начало дня: ВремяВСекундах = МояДата - НачалоДня(МояДата). Результат — число секунд с полуночи, которое можно разложить на часы и минуты делением на 3600 и 60. Для отображения используйте форматирование с шаблоном времени.

Почему ДобавитьМесяц(31.01, 1) не даёт 28 или 29 февраля «того же числа»?

Потому что 31 февраля не существует. Функция в таких случаях возвращает последний день целевого месяца. Если для бизнес-логики критичен именно день месяца (например, ежемесячный платёж 31-го), это поведение нужно обрабатывать отдельно в коде.

Как в запросе отобрать документы за конкретный день, если у дат есть время?

Используйте диапазон: условие Дата >= НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И Дата <= КОНЕЦПЕРИОДА(&Дата, ДЕНЬ). Это надёжнее, чем сравнение на равенство, которое не сработает из-за отличающегося времени.