Разработка и Конфигурация · 9 мин
Как к дате прибавить дни в 1С
Как прибавить дни к дате в 1С: сложение с секундами, функция ДобавитьМесяц, работа с календарями и запросами. Примеры кода, типичные ошибки и проверка результата.
Задача прибавить к дате несколько дней возникает в 1С постоянно: расчёт срока оплаты по договору, дата отгрузки, окончание отпуска, срок хранения документа. Встроенный язык платформы не содержит отдельной функции вида «ДобавитьДни», поэтому используются два рабочих подхода — арифметика с секундами и функция ДобавитьМесяц для календарных сдвигов. Оба способа просты, но у каждого есть ограничения, о которых нужно знать до внедрения кода в прикладное решение.
Дата в 1С хранится с точностью до секунды, поэтому сложение дат выполняется через число секунд. Один день — это 86400 секунд. Если нужно сдвинуть дату на неделю, прибавляют 7 * 86400. Такой подход корректно переносит переходы через конец месяца и года: платформа сама пересчитает значение, потому что внутри дата представлена как числовое значение, а не как текст.
Базовый способ: прибавление дней через секунды
Самый распространённый приём — сложение даты с числом секунд. Поскольку тип Дата в 1С поддерживает арифметические операции с числами, выражение Дата + 86400 вернёт дату на сутки позже. Для удобства чтения кода количество секунд в дне часто выносят в переменную или вычисляют как 60 60 24.
ИсходнаяДата = ТекущаяДатаСеанса();
КоличествоДней = 10;
НоваяДата = ИсходнаяДата + КоличествоДней <em> 86400;
// 86400 = 60 секунд </em> 60 минут * 24 часаВычитание работает симметрично: НоваяДата = ИсходнаяДата - 5 * 86400 вернёт дату на пять дней раньше. Разность двух дат в 1С тоже даёт число секунд, поэтому обратная проверка проста: (НоваяДата - ИсходнаяДата) / 86400 должна дать исходное количество дней.
Если исходное значение содержало 14:30:00, то результат сохранит то же время суток. Когда время не нужно, применяйте функции НачалоДня или КонецДня к результату — это уберёт неожиданные расхождения при сравнении дат в отчётах и запросах.
Функция ДобавитьМесяц: когда дни не подходят
Если нужно сдвинуть дату на месяц или год, складывать секунды нельзя: месяцы имеют разную длину. Для этого во встроенном языке есть функция ДобавитьМесяц(Дата, КоличествоМесяцев). Она корректно обрабатывает границы: при добавлении месяца к 31 января результатом будет последний день февраля, а не несуществующая дата.
ДатаДоговора = '20260131';
ДатаОкончания = ДобавитьМесяц(ДатаДоговора, 1); // последний день февраля
ДатаГодомПозже = ДобавитьМесяц(ДатаДоговора, 12);Отрицательный аргумент сдвигает дату назад: ДобавитьМесяц(Дата, -3) вернёт дату тремя месяцами ранее. Это удобно для расчёта начала отчётного периода, даты начала просрочки и подобных сценариев.
Комбинация двух подходов встречается часто: сначала сдвинуть дату на месяцы, затем откорректировать на дни. Например, «срок оплаты — один месяц и десять дней с даты счёта» вычисляется как ДобавитьМесяц(ДатаСчета, 1) + 10 * 86400.
Прибавление дней в запросах
В языке запросов 1С арифметика с датами ограничена: складывать дату с числом напрямую нельзя. Для сдвига дат в запросе используется функция ДОБАВИТЬКДАТЕ(Дата, Тип, Количество), где тип — одно из ключевых слов: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД, ДЕКАДА, ПОЛУГОДИЕ.
ВЫБРАТЬ
Реализация.Дата КАК ДатаДокумента,
ДОБАВИТЬКДАТЕ(Реализация.Дата, ДЕНЬ, Реализация.Договор.СрокОплатыДней) КАК СрокОплаты
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияФункция РАЗНОСТЬДАТ(Дата1, Дата2, Тип) позволяет выполнить обратную операцию — узнать, сколько дней между двумя датами, что полезно для контроля просрочек. Например, РАЗНОСТЬДАТ(СрокОплаты, &ТекущаяДата, ДЕНЬ) > 0 означает, что срок уже наступил.
Учитывайте, что вычисления в запросе выполняются на сервере СУБД и не имеют доступа к функциям встроенного языка. Если логика сложная — например, учёт рабочих дней по календарю — её лучше реализовать в коде после выборки данных, а не пытаться выразить всё в запросе.
Расчёт рабочих дней по производственному календарю
Прибавление календарных дней и прибавление рабочих дней — разные задачи. Для сроков, зависящих от рабочих дней (банковские операции, кадровые документы, логистика), простое сложение секунд не подходит: результат может попасть на выходной или праздник.
В типовых конфигурациях для этого используется регистр сведений с данными производственного календаря (в БСП — подсистема «Календарные графики»). Алгоритм обычно такой: в цикле прибавляем по одному дню и проверяем по календарю, является ли день рабочим; счётчик рабочих дней увеличивается только для рабочих дат, пока не достигнет нужного количества.
Если календарь не заполнен на нужный год, расчёт даст неверный результат без какого-либо сообщения об ошибке. Перед внедрением такого кода добавьте проверку наличия данных календаря за требуемый период и понятное сообщение пользователю при их отсутствии.
Типичные ошибки и как их избежать
Самая частая ошибка — попытка прибавить дни к строковому представлению даты. Если дата хранится в реквизите типа Строка, сложение либо вызовет ошибку, либо даст непредсказуемый результат. Перед вычислениями убедитесь, что реквизит имеет тип Дата, а строки преобразовывайте функцией Дата() только там, где это допустимо.
Вторая распространённая проблема — игнорирование времени в составе даты. Сравнение Дата1 = Дата2 вернёт Ложь, если время различается хотя бы на секунду, даже когда календарный день один. Для сравнения дат без времени используйте НачалоДня с обеих сторон.
Ещё одна ловушка — пустая дата. Значение '00010101' при сложении с днями даст дату в начале летоисчисления, что потом «поедет» в отчёты и печатные формы. Перед расчётом проверяйте ЗначениеЗаполнено(Дата).
Проверка результата вычислений
После реализации расчёта проверьте его на граничных случаях: переход через конец месяца, конец года, високосный февраль. Для этого достаточно вычислить в отладчике или консоли кода несколько контрольных примеров и сверить с календарём.
Как проверить результат
31.01 + 1 день = 01.02
Получилась та же дата или ошибка преобразования
Время соответствует ожиданию (сохранено или обнулено НачалоДня)
Неожиданное время мешает сравнению дат
(Результат - ИсходнаяДата) / 86400 равно числу дней
Дробное или иное значение
Расчёт не выполняется, есть проверка ЗначениеЗаполнено
Результат — дата в году 1
Полезный приём — написать небольшую проверочную процедуру с набором пар «исходная дата — ожидаемый результат» и запускать её после изменений в коде расчёта. Это дешёвый способ не пропустить регрессию при доработках.
Частые вопросы
Можно ли прибавить дни к дате без кода, например в настройке отчёта?
В СКД и динамических списках доступны выражения на языке выражений компоновки, где есть вычисления с датами, но возможности ограничены. Для простых сдвигов проще добавить вычисляемое поле в запросе через ДОБАВИТЬКДАТЕ. Сложную логику с рабочими днями в отчёте без доработки кода реализовать не получится.
Как прибавить часы или минуты, а не дни?
Тем же сложением с секундами: час — это 3600 секунд, минута — 60. Выражение Дата + 2 * 3600 сдвинет дату-время на два часа. В запросе для этого есть типы ЧАС и МИНУТА в функции ДОБАВИТЬКДАТЕ.
Почему после прибавления дней дата сравнивается неправильно?
Чаще всего причина во времени в составе даты: исходное значение содержало время, и результат тоже его содержит. Приведите обе даты к началу дня функцией НачалоДня перед сравнением, либо используйте интервалы с НачалоДня и КонецДня.
Как посчитать количество дней между двумя датами?
Вычтите одну дату из другой — получите разность в секундах — и разделите на 86400: ДнейМежду = (Дата2 - Дата1) / 86400. В запросе используйте РАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ). Учтите, что при наличии времени результат может быть дробным; округлите или приведите даты к началу дня.
Что делать, если нужно прибавлять дни с учётом графика работы конкретного сотрудника?
Используйте не общий производственный календарь, а график работы сотрудника — в типовых конфигурациях это отдельные справочники графиков с собственными данными о рабочих днях. Логика цикла та же, но проверка дня выполняется по данным конкретного графика.
Работает ли сложение дат в тонком клиенте и на мобильной платформе?
Арифметика дат и функция ДобавитьМесяц доступны во всех клиентах, включая веб-клиент и мобильную платформу. Ограничения касаются серверных вызовов: если расчёт обращается к данным календаря в базе, он должен выполняться на сервере.
Что важно запомнить
Дни к дате прибавляют сложением с секундами: Дата + N * 86400. Месяцы и годы сдвигают функцией ДобавитьМесяц, в запросах — ДОБАВИТЬКДАТЕ. Для рабочих дней нужен производственный календарь, а перед расчётом стоит проверять тип значения, заполненность даты и время в её составе.