Разработка и Конфигурация · 9 мин
Как в 1С добавить к дате дни: все рабочие способы
Как в 1С прибавить дни к дате: функция ДобавитьКДате, сложение с секундами, запросы с ДОБАВИТЬКДАТЕ, учет рабочих дней и типичные ошибки разработчиков.
Работа с датами — одна из самых частых задач при разработке и доработке конфигураций 1С. Нужно рассчитать срок оплаты по договору, дату отгрузки, окончание испытательного срока или период действия скидки — везде требуется прибавить к дате определенное количество дней. Встроенный язык 1С предлагает для этого несколько инструментов, и у каждого есть свои особенности, которые важно понимать, чтобы не получить ошибку в расчетах.
Главное, что нужно знать сразу: тип «Дата» в 1С хранит значение с точностью до секунды, поэтому простое сложение вида Дата + Число прибавляет не дни, а секунды. Это самая распространенная причина ошибок у начинающих разработчиков. Правильных подходов два: универсальная функция ДобавитьКДате() и сложение с пересчетом дней в секунды.
Ниже разобраны все рабочие способы — от встроенного языка до языка запросов, с примерами кода, проверкой результата и разбором типичных ошибок.
Функция ДобавитьКДате — основной способ
Стандартная и рекомендуемая функция встроенного языка для арифметики с датами — ДобавитьКДате(). Она принимает три параметра: исходную дату, тип увеличения (строка) и величину изменения (число).
НоваяДата = ДобавитьКДате(ТекущаяДата(), "День", 10);
Второй параметр задает единицу измерения. Для работы с днями используется значение "День", но функция поддерживает и другие интервалы: "Секунда", "Минута", "Час", "Неделя", "Месяц", "Квартал", "Полугодие", "Год". Это делает функцию универсальной — тем же вызовом можно прибавить к дате, например, три месяца, не заботясь о разной длине месяцев.
Ключевое преимущество ДобавитьКДате() — корректная обработка календарных переходов. Если прибавить 5 дней к 29 января, результатом будет 3 февраля, а не несуществующее «34 января». Функция сама учитывает високосные годы и разное количество дней в месяцах.
Чтобы вычесть дни, передайте отрицательное число:
ДатаНеделюНазад = ДобавитьКДате(ТекущаяДата(), "День", -7);
Сложение даты с числом: когда прибавляются секунды
Второй способ — арифметический. В 1С к дате можно прибавить число, и платформа интерпретирует это число как количество секунд. Поскольку в сутках 86 400 секунд (60 × 60 × 24), прибавление дней выглядит так:
НоваяДата = ИсходнаяДата + 10 * 86400;
Чтобы код читался проще, часто выносят число секунд в отдельную переменную или константу:
СекундВДне = 86400;
СрокОплаты = ДатаДокумента + 14 * СекундВДне;
Этот способ работает быстро и часто встречается в типовом коде. Однако у него есть тонкость: если исходная дата содержит время (например, дата документа 15.03 14:30), то результат сохранит то же время. Для большинства расчетов это нормально, но если нужно начало дня результата, применяйте функцию НачалоДня():
НоваяДата = НачалоДня(ИсходнаяДата + 10 * 86400);
Сравнение способов
Универсально, читаемо, поддерживает месяцы и годы. Чуть многословнее при простом добавлении дней.
Коротко и быстро, но работает только с интервалами, кратными секундам. Нельзя так прибавить месяц — месяцы имеют разную длину.
Единственный вариант, когда расчет нужен прямо в выборке данных, без обхода результата запроса.
Как прибавить дни к дате в запросе
Если расчет нужно выполнить в запросе — например, выбрать документы с рассчитанным сроком оплаты — используется конструкция языка запросов ДОБАВИТЬКДАТЕ. Синтаксис похож на функцию встроенного языка:
ВЫБРАТЬ
Заказ.Дата КАК Дата,
ДОБАВИТЬКДАТЕ(Заказ.Дата, ДЕНЬ, 14) КАК СрокОплаты
ИЗ
Документ.ЗаказПокупателя КАК Заказ
Обратите внимание на различие: в запросе единица измерения пишется без кавычек — ДЕНЬ, МЕСЯЦ, ГОД, а не строкой. Это частая ошибка при переносе логики из модуля в запрос.
Третий параметр может быть не только литералом, но и выражением — например, полем из таблицы или параметром запроса. Это удобно, когда у каждого контрагента свой срок отсрочки, хранящийся в справочнике.
Практические сценарии использования
Расчет срока оплаты по договору
Типовая задача: от даты отгрузки прибавить срок отсрочки платежа, указанный в договоре. Если срок хранится в днях, код в модуле объекта выглядит так:
СрокОплаты = ДобавитьКДате(ДатаОтгрузки, "День", Договор.ОтсрочкаПлатежаДней);
Если договор задает срок в месяцах (например, «оплата в течение одного месяца»), меняется только второй параметр — на "Месяц". При этом 31 января плюс один месяц даст последний день февраля, что обычно и ожидается в бухгалтерских расчетах.
Расчет даты с учетом только рабочих дней
Здесь начинается ограничение обоих способов: ни ДобавитьКДате(), ни сложение не знают ничего о производственном календаре. Если по условиям задачи нужно прибавить 5 рабочих дней, простое сложение даст неверный результат, когда в интервал попадают выходные и праздники.
Решение строится на регистре сведений с данными производственного календаря (в типовых конфигурациях он называется «ДанныеПроизводственногоКалендаря» или аналогично). Алгоритм такой: в цикле прибавлять по одному дню и проверять по календарю, является ли день рабочим, пока не наберется нужное количество рабочих дней. В типовых конфигурациях часто есть готовые функции общих модулей для такого расчета — стоит поискать их до написания собственного велосипеда.
Прибавление дней к дате в форме и в реквизитах
Когда пользователь вводит дату в форме, а смежное поле должно пересчитаться автоматически, расчет размещают в обработчике события ПриИзменении поля ввода:
&НаКлиенте
Процедура ДатаНачалаПриИзменении(Элемент)
Объект.ДатаОкончания = ДобавитьКДате(Объект.ДатаНачала, "День", 30);
КонецПроцедуры
Функция ДобавитьКДате() доступна и на клиенте, и на сервере, поэтому отдельный серверный вызов для такого расчета не нужен — это экономит обращения к серверу.
Проверка результата и типичные ошибки
После внедрения расчета убедитесь, что он ведет себя правильно на граничных значениях: конец месяца, конец года, високосный февраль. Проще всего проверить код в консоли кода или через «Вычислить выражение» в отладчике, подставив даты вроде 31.01, 28.02 високосного года и 31.12.
Еще один источник путаницы — пустая дата. Если исходная дата не заполнена (значение '00010101'), прибавление дней даст дату в январе первого года, что почти наверняка не входит в ваши планы. Перед расчетом проверяйте заполненность:
Если ЗначениеЗаполнено(ИсходнаяДата) Тогда
НоваяДата = ДобавитьКДате(ИсходнаяДата, "День", 10);
КонецЕсли;
Как проверить результат
29 января + 5 дней = 3 февраля
Дата осталась в январе или съехала на секунды
Время результата соответствует ожиданию (сохранено или обнулено явно)
Неожиданные часы и минуты ломают сравнения дат
Расчет пропускается или выдает понятное значение по умолчанию
В результате появляется январь 0001 года
Расчет идет через производственный календарь
Выходные и праздники засчитаны как рабочие
Часто задаваемые вопросы
Как прибавить к дате один день в 1С?
Используйте ДобавитьКДате(Дата, "День", 1) или выражение Дата + 86400. Оба варианта корректно переносят дату на следующие сутки, включая переход через конец месяца и года.
Почему Дата + 10 не прибавляет 10 дней?
Потому что при сложении даты с числом платформа 1С трактует число как секунды. Чтобы прибавить 10 дней, умножьте количество на число секунд в сутках: Дата + 10 * 86400, либо используйте ДобавитьКДате(Дата, "День", 10).
Как вычесть дни из даты?
Передайте в ДобавитьКДате отрицательное значение: ДобавитьКДате(Дата, "День", -5) вернет дату на пять дней раньше. Арифметический вариант — Дата - 5 * 86400.
Как прибавить дни к дате в запросе 1С?
Примените конструкцию ДОБАВИТЬКДАТЕ(ПолеДаты, ДЕНЬ, КоличествоДней) в списке выбираемых полей. Обратите внимание: тип интервала ДЕНЬ пишется без кавычек, в отличие от функции встроенного языка.
Как прибавить рабочие дни, а не календарные?
Стандартные функции этого не умеют. Нужно в цикле прибавлять по одному дню и проверять по производственному календарю, рабочий ли он, пока не наберется требуемое число рабочих дней. В типовых конфигурациях поищите готовые функции в общих модулях работы с календарями.
Чем отличается ДобавитьКДате с типом «Месяц» от прибавления 30 дней?
Прибавление месяца учитывает реальный календарь: к 31 января добавится февраль с его фактической длиной. Прибавление 30 дней просто сдвинет дату на фиксированный интервал, и результат может попасть на другую календарную дату, чем ожидалось в договорных условиях.
Что важно запомнить
Для прибавления дней к дате в 1С используйте ДобавитьКДате(Дата, "День", N) — функция сама обрабатывает переходы месяцев и лет. Арифметическое сложение работает через секунды: Дата + N * 86400. В запросах применяйте ДОБАВИТЬКДАТЕ с типом ДЕНЬ без кавычек. Для расчетов по рабочим дням нужен производственный календарь, а пустые даты и составляющая времени требуют отдельной проверки.