Разработка и Конфигурация · 12 мин
Как добавить к дате в 1С: способы, функции и примеры
Как прибавить к дате дни, месяцы, часы и секунды в 1С: функция ДобавитьКДате, оператор +, работа с датами в запросах, типичные ошибки и примеры кода.
Работа с датами — одна из самых частых задач в 1С: рассчитать срок оплаты, получить дату окончания договора, определить границу периода отчёта. Встроенный язык платформы предлагает для этого два основных инструмента: функцию ДобавитьКДате() и арифметический оператор сложения. У каждого способа есть свои особенности, и выбор неправильного варианта приводит к ошибкам, которые сложно заметить — например, к «потере» дня при переходе через конец месяца.
Главное, что нужно понять сразу: тип «Дата» в 1С хранится с точностью до секунды, а сложение через оператор + работает именно в секундах. Поэтому «прибавить один день» и «прибавить 86400 секунд» — формально одно и то же, но «прибавить один месяц» через секунды корректно не сделать: в месяцах разное количество дней. Для календарных периодов существует отдельная функция, которая учитывает структуру календаря.
Ниже разобраны все рабочие способы: добавление дней, месяцев, лет и времени в коде, работа с датами в запросах, типичные ошибки и способы проверить результат. Примеры приведены для встроенного языка 1С и актуальны для управляемых и обычных форм любых типовых и самописных конфигураций.
Функция ДобавитьКДате: синтаксис и типы периодов
Функция ДобавитьКДате() — основной и рекомендуемый способ сдвига даты на календарный период. Она корректно обрабатывает переходы через конец месяца, високосные годы и разную длину месяцев, чего нельзя добиться простым сложением секунд.
Синтаксис функции:
НоваяДата = ДобавитьКДате(ИсходнаяДата, ТипПериода, Количество);
Первый параметр — исходная дата (значение типа «Дата»). Второй — строковое обозначение типа периода. Третий — число периодов; оно может быть отрицательным, тогда дата сдвинется назад. Допустимые значения типа периода: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ПОЛУГОДИЕ, ГОД, ДЕСЯТИЛЕТИЕ, ВЕК.
// Прибавить 10 дней к дате документа
ДатаОплаты = ДобавитьКДате(ДатаДокумента, "ДЕНЬ", 10);
// Прибавить 3 месяца — срок действия договора
ДатаОкончания = ДобавитьКДате(ДатаНачала, "МЕСЯЦ", 3);
// Вычесть 1 год (отрицательное количество)
ГодНазад = ДобавитьКДате(ТекущаяДата(), "ГОД", -1);
Важная особенность: если исходная дата — последний день месяца, а целевой месяц короче, функция вернёт последний день целевого месяца. Например, ДобавитьКДате('20260131', "МЕСЯЦ", 1) даст 29 февраля, а не 2 марта. Это поведение соответствует календарной логике, но его нужно учитывать в расчётах сроков.
Сложение даты и числа: когда уместен оператор «плюс»
Второй способ — арифметическое сложение: НоваяДата = Дата + ЧислоСекунд. Платформа интерпретирует число как количество секунд. Этот приём короткий и удобный, когда нужен точный сдвиг по времени: прибавить 15 минут к времени начала события, сдвинуть дату на сутки, получить конец интервала.
// Прибавить одни сутки (86400 секунд)
Завтра = ТекущаяДата() + 86400;
// Прибавить 30 минут
ВремяОкончания = ВремяНачала + 30 * 60;
// Вычесть 2 часа
СдвигНазад = ДатаВремя - 7200;
Ограничение способа принципиально: через секунды нельзя корректно прибавить месяц, квартал или год, потому что их длительность в секундах непостоянна. Код вида Дата + 30 * 86400 для «месяца» даст ошибку в 1–3 дня в зависимости от месяца. Для календарных периодов всегда используйте ДобавитьКДате().
Сравнение способов
Подходит для календарных периодов: день, неделя, месяц, год. Корректно обрабатывает конец месяца и високосные годы. Чуть многословнее в записи.
Подходит для точных сдвигов по времени: секунды, минуты, часы, сутки. Не применим для месяцев и лет из-за переменной длительности.
Используется, когда сдвиг даты нужен прямо в выборке: фильтрация по периоду, расчёт сроков на стороне СУБД без обхода результата запроса.
Как прибавить дни, месяцы и годы: практические сценарии
Срок оплаты по договору
Типовая задача — рассчитать дату оплаты как дату отгрузки плюс отсрочка в днях. Здесь подходит и ДобавитьКДате, и сложение, но первый вариант читается лучше:
ОтсрочкаДней = 14;
ДатаОплаты = ДобавитьКДате(ДатаОтгрузки, "ДЕНЬ", ОтсрочкаДней);
Если по условиям договора оплата должна приходиться на рабочий день, одного сдвига недостаточно: потребуется проверка по производственному календарю (регистр сведений «ДанныеПроизводственногоКалендаря» в типовых конфигурациях) и, при необходимости, перенос на следующий рабочий день в цикле.
Дата окончания договора или подписки
Для периодов в месяцах и годах используйте только ДобавитьКДате. Частая бизнес-логика: договор действует «по день накануне годовщины», то есть от результата нужно отнять одни сутки:
// Договор на 1 год: с 15 марта по 14 марта следующего года
ДатаОкончания = ДобавитьКДате(ДатаНачала, "ГОД", 1) - 86400;
Отнимание суток после добавления года — рабочий приём, но проверяйте граничные случаи: если начало 29 февраля, результат сдвига на год даст 28 февраля, и логика «минус день» может потребовать уточнения с заказчиком.
Расчёт границ периода отчёта
Для отчётов часто нужны начало и конец периода. Используйте связку стандартных функций: НачалоДня(), КонецДня(), НачалоМесяца(), КонецМесяца() в сочетании со сдвигом:
// Прошлый месяц целиком
НачалоПериода = НачалоМесяца(ДобавитьКДате(ТекущаяДата(), "МЕСЯЦ", -1));
КонецПериода = КонецМесяца(НачалоПериода);
Обратите внимание: КонецДня() и КонецМесяца() возвращают время 23:59:59. Если дальше дата сравнивается с датами документов, у которых время может быть любым, такая граница корректна. А вот при передаче в запрос в качестве параметра виртуальной таблицы иногда надёжнее использовать «меньше начала следующего дня».
- 1Определите, календарный это период (месяц, год) или точный (часы, сутки)
- 2Для календарного периода вызовите ДобавитьКДате с нужным типом периода
- 3Для точного сдвига используйте сложение с количеством секунд
- 4Если результат должен быть рабочим днём — проверьте его по производственному календарю
- 5Проверьте граничные случаи: конец месяца, 29 февраля, пустая дата
Добавление к дате в запросах
В языке запросов 1С есть функция ДОБАВИТЬКДАТЕ(Дата, Тип, Количество) с аналогичной логикой. Она позволяет сдвигать даты прямо в выборке — без обхода результата в коде. Тип периода указывается без кавычек: ДЕНЬ, МЕСЯЦ, ГОД, ЧАС, МИНУТА, СЕКУНДА и другие.
ВЫБРАТЬ
Реализация.Ссылка КАК Документ,
ДОБАВИТЬКДАТЕ(Реализация.Дата, ДЕНЬ, 14) КАК ДатаОплаты
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода
Практическое применение: отбор документов с наступающим сроком оплаты, расчёт просрочки, вычисление даты окончания гарантии в отчёте. Условие вида ДОБАВИТЬКДАТЕ(Дата, ДЕНЬ, 14) <= &ТекущаяДата выберет все документы, по которым срок оплаты уже наступил.
Ограничение: количество периодов в ДОБАВИТЬКДАТЕ должно быть целым числом, и не все комбинации поддерживаются одинаково на разных СУБД. Сложные вычисления над датами (например, с учётом производственного календаря) в запросе выполнить нельзя — их выносят в код после получения выборки.
Работа с временем и пустыми датами
Дата в 1С всегда содержит время, даже если оно не отображается. ДобавитьКДате(Дата, "ЧАС", 5) сдвинет и дату, и время; если исходное время было 22:00, результат перейдёт на следующие сутки. Это нормальное поведение, но оно может «сломать» отборы по дате, если вы ожидали, что день не изменится.
Отдельная ловушка — пустая дата '00010101000000'. Сдвиг пустой даты технически выполнится (получится дата января 1 года плюс период), но бизнес-смысла в этом нет. Перед расчётом проверяйте заполненность:
Если ЗначениеЗаполнено(ДатаОтгрузки) Тогда
ДатаОплаты = ДобавитьКДате(ДатаОтгрузки, "ДЕНЬ", Отсрочка);
Иначе
ДатаОплаты = Неопределено;
КонецЕсли;
Если нужно получить только дату без времени после сдвига, оберните результат в НачалоДня(). Это особенно важно при сравнениях: Дата1 = Дата2 сравнивает значения с точностью до секунды, и разница во времени сделает равные «календарно» даты неравными.
Типичные ошибки и как их проверить
Первая ошибка — прибавление «месяца» как 30 суток. На длинных интервалах расхождение накапливается: за год набегает до пяти дней. Вторая — сравнение дат без приведения к началу дня, из-за чего документ «выпадает» из отбора. Третья — забытый сдвиг времени при работе с ТекущаяДата(), которая содержит текущее время сеанса.
Четвёртая распространённая проблема — часовые пояса. Если база работает в нескольких часовых поясах, ТекущаяДата() возвращает дату сеанса, а хранимые даты документов могут относиться к другому поясу. Сдвиг на сутки в таком случае может дать неожиданный календарный день у части пользователей.
Проверка результата — обязательный этап. Прогоните расчёт на граничных датах: 31 января при сдвиге на месяц, 29 февраля високосного года при сдвиге на год, 31 декабря при сдвиге на день. Сверьте результат с календарём вручную — это занимает минуту и отсекает большинство дефектов.
Как проверить результат
Результат — последний день февраля (28 или 29 число)
Результат — 2–3 марта: вероятно, использовано сложение секунд
Обе даты приведены к НачалоДня() или границы заданы интервалом
Документы с ненулевым временем не попадают в выборку
Перед расчётом стоит проверка ЗначениеЗаполнено
В реквизитах появляются даты января года 1
Что важно запомнить
Календарные периоды (день, месяц, год) добавляйте функцией ДобавитьКДате, точные сдвиги по времени — сложением секунд, в запросах используйте ДОБАВИТЬКДАТЕ. Всегда проверяйте заполненность исходной даты и тестируйте расчёт на границах месяца и високосного года.
Частые вопросы
Как прибавить к дате один день в 1С?
Два равнозначных способа: ДобавитьКДате(Дата, "ДЕНЬ", 1) или Дата + 86400 (сутки в секундах). Для одного дня оба варианта дают одинаковый результат; первый читается нагляднее.
Как вычесть из даты месяц?
Передайте отрицательное количество: ДобавитьКДате(Дата, "МЕСЯЦ", -1). Учтите, что от 31 марта результатом будет последний день февраля, а не «31 февраля».
Чем отличается ДобавитьКДате от сложения с числом?
Сложение с числом сдвигает дату на указанное количество секунд и не знает ничего о календаре. ДобавитьКДате работает с календарными периодами и корректно обрабатывает разную длину месяцев и високосные годы.
Как прибавить к дате только рабочие дни?
Штатной функции для этого нет. Нужно в цикле сдвигать дату по одному дню и проверять каждый день по данным производственного календаря (в типовых конфигурациях — регистр сведений с данными календаря), считая только рабочие дни.
Почему после ДобавитьКДате дата не равна ожидаемой при сравнении?
Скорее всего, даты содержат разное время. Сравнение дат в 1С идёт с точностью до секунды. Приведите обе даты к началу дня функцией НачалоДня() перед сравнением.
Можно ли прибавить к дате дробное количество периодов?
Нет, третий параметр ДобавитьКДате — целое число. Для дробных сдвигов пересчитайте их в секунды и используйте сложение: например, полтора часа — это Дата + 5400.