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