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

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

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

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

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

Главное, что нужно понимать: дата в 1С — это не число, а отдельный тип данных, хранящий значение с точностью до секунды. Поэтому просто написать «Дата + 1» нельзя — платформа выдаст ошибку о несоответствии типов. Корректных способов два: функция ДобавитьКДате() и прибавление количества секунд.

Ниже разобраны оба подхода, работа с датами в запросах, обработка граничных случаев (конец месяца, високосный год) и типичные ошибки, которые допускают даже опытные разработчики.

Функция ДобавитьКДате — основной способ

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

НоваяДата = ДобавитьКДате(ИсходнаяДата, "ДЕНЬ", 1);

Функция возвращает новое значение типа «Дата», не изменяя исходную переменную. Это важно: если нужно сохранить результат, его обязательно присваивают переменной или реквизиту. Тип интервала можно указывать как на русском («ДЕНЬ»), так и на английском («DAY») — оба варианта допустимы независимо от варианта встроенного языка конфигурации.

Кроме дней поддерживаются интервалы СЕКУНДА, МИНУТА, ЧАС, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ПОЛУГОДИЕ и ГОД. Это позволяет одной функцией решать любые задачи смещения дат. Для вычитания передаётся отрицательное число: ДобавитьКДате(Дата, "ДЕНЬ", -1) вернёт вчерашнюю дату.

1c
// Добавить один день
Завтра = ДобавитьКДате(ТекущаяДатаСеанса(), "ДЕНЬ", 1);

// Добавить 14 дней к дате документа
СрокОплаты = ДобавитьКДате(Объект.Дата, "ДЕНЬ", 14);

// Вычесть 3 дня
ДатаНапоминания = ДобавитьКДате(СрокОплаты, "ДЕНЬ", -3);

Как ведёт себя функция на границах месяца и года

Главное преимущество ДобавитьКДате() — корректная календарная арифметика. Если к 31 января прибавить один день, результатом будет 1 февраля, а не «32 января». Переход через год обрабатывается так же: 31 декабря плюс один день даст 1 января следующего года.

Високосные годы учитываются автоматически: прибавление дня к 28 февраля високосного года даст 29 февраля, а невисокосного — 1 марта. Разработчику не нужно реализовывать эту логику вручную.

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

Альтернатива: прибавление секунд

Второй рабочий способ — прибавить к дате число, которое платформа интерпретирует как количество секунд. В сутках 86400 секунд, поэтому добавление дня выглядит так:

НоваяДата = ИсходнаяДата + 86400; // один день

НоваяДата = ИсходнаяДата + 7 * 86400; // неделя

Способ короче и выполняется чуть быстрее, поэтому его часто используют в циклах при обходе диапазона дат. Однако у него есть ограничения: он не подходит для месяцев и лет (их длительность в секундах непостоянна), а код становится менее читаемым — по числу 86400 не всегда очевидно намерение автора.

Хорошая практика — выносить длительность суток в именованную переменную или константу модуля, например СекундВДне = 86400;. Это снимает вопросы при код-ревью и снижает риск опечатки в количестве нулей.

Сравнение вариантов

ДобавитьКДате()

Универсально: дни, месяцы, годы. Корректные календарные переходы. Читаемый код. Чуть медленнее в массовых циклах.

Прибавление секунд

Подходит только для дней и меньших интервалов. Быстро и компактно, удобно в циклах по диапазону дат. Не работает для месяцев и лет.

ДОБАВИТЬКДАТЕ в запросе

Единственный вариант, когда смещение нужно прямо в запросе — например, для сравнения сроков в выборке без постобработки.

Добавление дня к дате в запросе

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

ВЫБРАТЬ

Реализация.Ссылка,

ДОБАВИТЬКДАТЕ(Реализация.Дата, ДЕНЬ, 10) КАК СрокОплаты

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ГДЕ

ДОБАВИТЬКДАТЕ(Реализация.Дата, ДЕНЬ, 10) <= &ТекущаяДата

Обратите внимание: в запросе тип интервала указывается без кавычек — ДЕНЬ, МЕСЯЦ, ГОД и так далее. Это частая ошибка при переносе логики из кода в запрос. Прибавление секунд арифметикой в запросе не поддерживается — только функция.

Если смещение нужно только для сравнения, иногда проще и быстрее инвертировать условие: вместо добавления дней к дате документа вычесть их из текущей даты параметра. Это позволяет платформе эффективнее использовать индексы по полю даты.

Типичные ошибки
01
Написать Дата + 1 — платформа выдаст ошибку, так как число прибавляется в секундах, а не в днях, а в ряде контекстов операция недопустима вовсе
02
Использовать в запросе "ДЕНЬ" в кавычках — синтаксическая ошибка, в запросе интервал пишется без кавычек
03
Ожидать, что ДобавитьКДате изменит исходную переменную — функция возвращает новое значение, результат нужно присваивать
04
Забыть про составляющую времени: дата документа обычно содержит время, и сравнение с «голой» датой может не сработать
05
Использовать секунды для добавления месяца (30 * 86400) — месяцы разной длины, результат будет неверным

Практические сценарии

Расчёт срока оплаты в документе

Типовая задача — при записи документа автоматически рассчитать дату оплаты как дату документа плюс отсрочка из договора. В модуле объекта это выглядит так:

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

Если ЗначениеЗаполнено(Договор) Тогда

СрокОплаты = ДобавитьКДате(Дата, "ДЕНЬ", Договор.ОтсрочкаПлатежаДней);

КонецЕсли;

КонецПроцедуры

Перед использованием реквизита договора убедитесь, что он заполнен и имеет числовой тип — иначе при пустом значении получите дату документа без смещения или ошибку приведения типа.

Цикл по диапазону дат

Когда нужно обработать каждый день периода — например, сформировать табель или проверить остатки на каждую дату — удобен цикл с прибавлением секунд:

ТекДата = НачалоДня(НачалоПериода);

Пока ТекДата <= КонецДня(КонецПериода) Цикл

// обработка даты ТекДата

ТекДата = ТекДата + 86400;

КонецЦикла;

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

Дата на форме и в реквизитах

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

Порядок действий
  1. 1
    Определите, где нужен расчёт: в коде модуля или в запросе
  2. 2
    Для кода используйте ДобавитьКДате(Дата, "ДЕНЬ", 1), для запроса — ДОБАВИТЬКДАТЕ(Дата, ДЕНЬ, 1)
  3. 3
    Присвойте результат переменной или реквизиту — исходное значение не изменится
  4. 4
    При необходимости нормализуйте время через НачалоДня() или КонецДня()
  5. 5
    Проверьте результат на граничных датах: конец месяца, конец года, 28 февраля

Проверка результата и отладка

Простейший способ проверить расчёт — вывести значения через Сообщить() или посмотреть их в отладчике. Убедитесь, что и исходная, и результирующая даты имеют ожидаемый тип и составляющую времени.

Для проверки граничных случаев полезно прогнать расчёт на контрольном наборе: 31 января, 28 февраля, 31 декабря. Если во всех случаях результат соответствует календарю — реализация корректна.

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

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

Добавление дня к 31.01
Норма

Результат 01.02 того же года

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

Ошибка или дата вне календаря

Составляющая времени
Норма

Время результата совпадает с исходным или обнулено намеренно

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

Неожиданные 00:00:00, ломающие сравнения

Тип результата
Норма

Тип «Дата»

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

Число или строка — значит, где-то выполнено неверное преобразование

FAQ

Как вычесть день из даты в 1С?

Используйте ту же функцию с отрицательным параметром: ДобавитьКДате(Дата, "ДЕНЬ", -1). Либо вычтите секунды: Дата - 86400. Оба способа корректно обрабатывают переход на предыдущий месяц.

Можно ли прибавить к дате только рабочие дни?

Штатной функции для рабочих дней нет. Нужно использовать регистр сведений с производственным календарём (в типовых конфигурациях — «РегламентированныйПроизводственныйКалендарь») и в цикле отсчитывать только рабочие дни по данным календаря.

Почему ДобавитьКДате не меняет мою переменную?

Функция возвращает новое значение и не модифицирует аргумент. Результат нужно присвоить: Дата = ДобавитьКДате(Дата, "ДЕНЬ", 1).

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

Передайте реквизит третьим параметром: ДОБАВИТЬКДАТЕ(Документ.Дата, ДЕНЬ, Документ.ОтсрочкаДней). Третий параметр может быть полем или параметром запроса, не обязательно литералом.

Что произойдёт при добавлении дня к пустой дате?

Пустая дата в 1С — это 01.01.0001 00:00:00. Добавление дня даст 02.01.0001, что почти наверняка не то, что нужно. Перед расчётом проверяйте заполненность через ЗначениеЗаполнено(Дата).

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

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

Итог

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

Для добавления дня к дате используйте ДобавитьКДате(Дата, "ДЕНЬ", 1) в коде и ДОБАВИТЬКДАТЕ(Дата, ДЕНЬ, 1) в запросах. Функция возвращает новое значение и корректно обрабатывает календарные переходы. Прибавление 86400 секунд — допустимая альтернатива для дней в циклах. Всегда проверяйте заполненность исходной даты и составляющую времени.