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

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

Как к дате прибавить дни в 1С

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

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

Дата в 1С хранится с точностью до секунды, поэтому сложение дат выполняется через число секунд. Один день — это 86400 секунд. Если нужно сдвинуть дату на неделю, прибавляют 7 * 86400. Такой подход корректно переносит переходы через конец месяца и года: платформа сама пересчитает значение, потому что внутри дата представлена как числовое значение, а не как текст.

Базовый способ: прибавление дней через секунды

Самый распространённый приём — сложение даты с числом секунд. Поскольку тип Дата в 1С поддерживает арифметические операции с числами, выражение Дата + 86400 вернёт дату на сутки позже. Для удобства чтения кода количество секунд в дне часто выносят в переменную или вычисляют как 60 60 24.

1c
ИсходнаяДата = ТекущаяДатаСеанса();
КоличествоДней = 10;
НоваяДата = ИсходнаяДата + КоличествоДней <em> 86400;
// 86400 = 60 секунд </em> 60 минут * 24 часа

Вычитание работает симметрично: НоваяДата = ИсходнаяДата - 5 * 86400 вернёт дату на пять дней раньше. Разность двух дат в 1С тоже даёт число секунд, поэтому обратная проверка проста: (НоваяДата - ИсходнаяДата) / 86400 должна дать исходное количество дней.

Если исходное значение содержало 14:30:00, то результат сохранит то же время суток. Когда время не нужно, применяйте функции НачалоДня или КонецДня к результату — это уберёт неожиданные расхождения при сравнении дат в отчётах и запросах.

Функция ДобавитьМесяц: когда дни не подходят

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

1c
ДатаДоговора = '20260131';
ДатаОкончания = ДобавитьМесяц(ДатаДоговора, 1); // последний день февраля
ДатаГодомПозже = ДобавитьМесяц(ДатаДоговора, 12);

Отрицательный аргумент сдвигает дату назад: ДобавитьМесяц(Дата, -3) вернёт дату тремя месяцами ранее. Это удобно для расчёта начала отчётного периода, даты начала просрочки и подобных сценариев.

Комбинация двух подходов встречается часто: сначала сдвинуть дату на месяцы, затем откорректировать на дни. Например, «срок оплаты — один месяц и десять дней с даты счёта» вычисляется как ДобавитьМесяц(ДатаСчета, 1) + 10 * 86400.

Прибавление дней в запросах

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

1c-query
ВЫБРАТЬ
	Реализация.Дата КАК ДатаДокумента,
	ДОБАВИТЬКДАТЕ(Реализация.Дата, ДЕНЬ, Реализация.Договор.СрокОплатыДней) КАК СрокОплаты
ИЗ
	Документ.РеализацияТоваровУслуг КАК Реализация

Функция РАЗНОСТЬДАТ(Дата1, Дата2, Тип) позволяет выполнить обратную операцию — узнать, сколько дней между двумя датами, что полезно для контроля просрочек. Например, РАЗНОСТЬДАТ(СрокОплаты, &ТекущаяДата, ДЕНЬ) > 0 означает, что срок уже наступил.

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

Расчёт рабочих дней по производственному календарю

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

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

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

Типичные ошибки и как их избежать

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

Вторая распространённая проблема — игнорирование времени в составе даты. Сравнение Дата1 = Дата2 вернёт Ложь, если время различается хотя бы на секунду, даже когда календарный день один. Для сравнения дат без времени используйте НачалоДня с обеих сторон.

Типичные ошибки
01
Сложение строки с числом вместо даты — преобразуйте значение к типу Дата перед расчётом
02
Сравнение дат с разным временем суток — применяйте НачалоДня или КонецДня
03
Использование 30 * 86400 как «месяца» — для месяцев есть ДобавитьМесяц
04
Расчёт рабочих дней без проверки заполненности производственного календаря
05
Сдвиг дат в запросе арифметикой вместо ДОБАВИТЬКДАТЕ

Ещё одна ловушка — пустая дата. Значение '00010101' при сложении с днями даст дату в начале летоисчисления, что потом «поедет» в отчёты и печатные формы. Перед расчётом проверяйте ЗначениеЗаполнено(Дата).

Проверка результата вычислений

После реализации расчёта проверьте его на граничных случаях: переход через конец месяца, конец года, високосный февраль. Для этого достаточно вычислить в отладчике или консоли кода несколько контрольных примеров и сверить с календарём.

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

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

Сдвиг через конец месяца
Норма

31.01 + 1 день = 01.02

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

Получилась та же дата или ошибка преобразования

Время в результате
Норма

Время соответствует ожиданию (сохранено или обнулено НачалоДня)

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

Неожиданное время мешает сравнению дат

Обратная разность
Норма

(Результат - ИсходнаяДата) / 86400 равно числу дней

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

Дробное или иное значение

Пустая исходная дата
Норма

Расчёт не выполняется, есть проверка ЗначениеЗаполнено

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

Результат — дата в году 1

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

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

Можно ли прибавить дни к дате без кода, например в настройке отчёта?

В СКД и динамических списках доступны выражения на языке выражений компоновки, где есть вычисления с датами, но возможности ограничены. Для простых сдвигов проще добавить вычисляемое поле в запросе через ДОБАВИТЬКДАТЕ. Сложную логику с рабочими днями в отчёте без доработки кода реализовать не получится.

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

Тем же сложением с секундами: час — это 3600 секунд, минута — 60. Выражение Дата + 2 * 3600 сдвинет дату-время на два часа. В запросе для этого есть типы ЧАС и МИНУТА в функции ДОБАВИТЬКДАТЕ.

Почему после прибавления дней дата сравнивается неправильно?

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

Как посчитать количество дней между двумя датами?

Вычтите одну дату из другой — получите разность в секундах — и разделите на 86400: ДнейМежду = (Дата2 - Дата1) / 86400. В запросе используйте РАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ). Учтите, что при наличии времени результат может быть дробным; округлите или приведите даты к началу дня.

Что делать, если нужно прибавлять дни с учётом графика работы конкретного сотрудника?

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

Работает ли сложение дат в тонком клиенте и на мобильной платформе?

Арифметика дат и функция ДобавитьМесяц доступны во всех клиентах, включая веб-клиент и мобильную платформу. Ограничения касаются серверных вызовов: если расчёт обращается к данным календаря в базе, он должен выполняться на сервере.

Итог

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

Дни к дате прибавляют сложением с секундами: Дата + N * 86400. Месяцы и годы сдвигают функцией ДобавитьМесяц, в запросах — ДОБАВИТЬКДАТЕ. Для рабочих дней нужен производственный календарь, а перед расчётом стоит проверять тип значения, заполненность даты и время в её составе.