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

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

Как прибавить год к дате в 1С

Как прибавить год к дате в 1С: функция ДобавитьМесяц, оператор ДОБАВИТЬКДАТЕ в запросах, работа с високосными годами и типичные ошибки разработчиков.

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

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

Материал применим к платформе 1С:Предприятие 8.2 и 8.3 в любых типовых и самописных конфигурациях — синтаксис работы с датами одинаков везде.

Почему нельзя прибавлять год через секунды

Дата в 1С внутренне хранится с точностью до секунды, и платформа позволяет выполнять арифметику напрямую: НоваяДата = СтараяДата + 3600 прибавит час. Из-за этого возникает соблазн написать Дата + 365 24 60 * 60 и считать, что год прибавлен.

Такой расчёт неверен. Год не равен фиксированному числу секунд: високосный год содержит 366 дней, а сдвиг на «средние» 365,25 дня даёт дату, смещённую на несколько часов от полуночи. Для документов и регистров, где важна точная дата начала дня, это приводит к ошибкам в отборах, проведении и отчётах.

Кроме того, арифметика секунд не понимает календарной семантики: «прибавить год к 29 февраля» должно дать 28 февраля следующего года, а не 1 марта или ошибку. Эту логику корректно реализуют только штатные календарные функции платформы.

Способ 1: функция ДобавитьМесяц во встроенном языке

Штатный способ прибавить год в коде — функция ДобавитьМесяц(Дата, ЧислоМесяцев). Год — это 12 месяцев, поэтому вызов выглядит так:

ДатаОкончания = ДобавитьМесяц(ДатаНачала, 12);

Функция работает календарно: к 15.03.2026 она вернёт 15.03.2026, к 31.01.2026 при добавлении одного месяца вернёт 29.02.2026 (последний день февраля), потому что 31 февраля не существует. Тот же принцип действует и при добавлении 12 месяцев к 29 февраля високосного года — результатом будет 28 февраля следующего года.

Функция умеет работать и в обратную сторону: отрицательный аргумент вычитает период. ДобавитьМесяц(Дата, -12) вернёт дату годом раньше. Это удобно для расчёта начала отчётного периода по дате окончания.

bsl
Процедура РассчитатьСрокДоговора()
	ДатаЗаключения = Дата(2026, 3, 15);
	ДатаОкончания = ДобавитьМесяц(ДатаЗаключения, 12);
	// ДатаОкончания = 15.03.2026
	
	// Если договор действует "по дату включительно",
	// отнимаем одну секунду для конца периода:
	КонецДействия = ДатаОкончания - 1;
КонецПроцедуры

Тонкость с концом периода

Частая логическая ошибка: договор заключён 15.03.2026 сроком на год, и разработчик записывает дату окончания как 15.03.2026. Но по смыслу договор обычно действует «по 14.03.2026 включительно». Если дата окончания участвует в сравнениях вида ТекущаяДата <= ДатаОкончания, разница в один день меняет результат проверки.

Определите соглашение заранее: либо храните дату начала следующего периода и сравнивайте строгим неравенством, либо отнимайте день (или секунду) от результата ДобавитьМесяц. Главное — применять один подход во всей конфигурации.

Способ 2: оператор ДОБАВИТЬКДАТЕ в запросах

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

ВЫБРАТЬ

Договоры.Ссылка КАК Договор,

Договоры.ДатаЗаключения КАК ДатаЗаключения,

ДОБАВИТЬКДАТЕ(Договоры.ДатаЗаключения, ГОД, 1) КАК ДатаОкончания

ИЗ

Справочник.ДоговорыКонтрагентов КАК Договоры

Второй параметр задаёт единицу сдвига: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ПОЛУГОДИЕ, ГОД. Третий параметр — целое число, может быть отрицательным для сдвига назад.

Важное отличие от ДобавитьМесяц: в запросе нельзя передать параметр-выражение как тип периода — только литерал. Количество же может быть параметром запроса или выражением над полями выборки.

ДОБАВИТЬКДАТЕ в СКД и динамических списках

В схеме компоновки данных и в произвольных запросах динамических списков оператор работает так же. Это удобно для колонок вида «Осталось до окончания» или «Дата следующей поверки»: вычисление выполняется на сервере СУБД и не требует обхода выборки в коде.

Как прибавить год к текущей дате и к дате документа

Для текущей даты на сервере используйте ТекущаяДатаСеанса(), а не ТекущаяДата() — последняя на клиенте может отличаться от серверного времени и давать рассинхронизацию в расчётах сроков:

ГодНазад = ДобавитьМесяц(ТекущаяДатаСеанса(), -12);

ГодВперед = ДобавитьМесяц(ТекущаяДатаСеанса(), 12);

Для даты документа обращайтесь к реквизиту объекта. Учтите, что дата документа содержит время, поэтому при расчёте календарных сроков её часто предварительно обрезают до начала дня функцией НачалоДня():

ДатаДокумента = НачалоДня(ДокументОбъект.Дата);

СрокГодности = ДобавитьМесяц(ДатаДокумента, 12);

Если нужно прибавить год к произвольной дате, введённой пользователем в форме, достаточно проверить, что поле заполнено: пустая дата (01.01.0001) после добавления месяцев останется бессмысленной для бизнес-логики, и лучше явно сообщить пользователю о незаполненном поле.

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

Граничные случаи: високосный год и конец месяца

Самый коварный сценарий — 29 февраля. ДобавитьМесяц(Дата(2026, 2, 29), 12) вернёт 28.02.2026, потому что 2026 год не високосный. Платформа выбирает последний существующий день месяца. Обычно это желаемое поведение, но если бизнес-логика требует именно 1 марта — придётся реализовать его отдельно.

Аналогично ведёт себя добавление 12 месяцев к 31 числам: проблем не возникает, так как месяц в результате тот же, и число сохраняется. А вот при добавлении одиночных месяцев к 31.01, 31.03 и подобным датам результат «сжимается» до последнего дня короткого месяца — полезно помнить, если год вы прибавляете поэтапно.

Отдельный случай — начало и конец года. ДобавитьМесяц(Дата(2026, 12, 31), 12) корректно вернёт 31.12.2026, переход через границу года функция обрабатывает сама, никакой ручной корректировки номера года не требуется.

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

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

29.02 високосного года + 12 месяцев
Норма

28.02 следующего года

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

01.03 или ошибка преобразования

15.03.2026 + 12 месяцев
Норма

15.03.2026, время сохранено

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

Сдвиг на часы или день

Сравнение в условии срока действия
Норма

Граничная дата обрабатывается по принятому соглашению

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

Договор «просрочен» на день раньше или позже ожидаемого

Сравнение способов и выбор под задачу

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

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

ДобавитьМесяц в коде

Подходит для модулей объектов, форм, общих модулей. Гибкая работа с переменными, но недоступна внутри запроса.

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

Подходит для выборок, СКД, динамических списков. Вычисляется на стороне СУБД, но тип периода нельзя передать параметром.

Арифметика секунд

Не рекомендуется для календарных периодов. Допустима только для точных интервалов вроде «через 48 часов».

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

Типичные ошибки
01
Прибавление 31536000 секунд вместо календарного года — сдвиг на високосных годах и неточное время
02
Использование ТекущаяДата() на клиенте для расчёта сроков — рассинхронизация с серверным временем
03
Запись даты окончания без соглашения «включительно/исключительно» — ошибки на один день в проверках сроков
04
Игнорирование пустой даты — ДобавитьМесяц от 01.01.0001 даёт формально валидный, но бессмысленный результат
05
Сложение года по месяцам в цикле от 31-го числа — накопление сжатия до конца коротких месяцев

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

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

Если расчёт влияет на проведение документов или движения по регистрам, прогоните тест на копии базы: перепроведите документы на границах периодов и сверьте отчёты до и после изменения. Изменение логики дат в действующей системе может «сдвинуть» сроки по уже существующим документам.

Удобно оформить расчёт срока как функцию общего модуля, например ДобавитьГод(Дата, ЧислоЛет). Тогда правило обработки 29 февраля и соглашение о конце периода зафиксированы в одном месте, и все прикладные объекты считают одинаково.
ПЗ
Практическое замечание

Часто задаваемые вопросы

Есть ли в 1С функция «ДобавитьГод»?

Нет, штатной функции с таким именем во встроенном языке нет. Год прибавляют через ДобавитьМесяц(Дата, 12) или создают собственную функцию-обёртку в общем модуле. В языке запросов год доступен напрямую через ДОБАВИТЬКДАТЕ с типом периода ГОД.

Что произойдёт, если прибавить год к 29 февраля?

ДобавитьМесяц вернёт 28 февраля следующего года, если он невисокосный, поскольку 29 февраля в нём не существует. Платформа выбирает последний существующий день месяца. Если прикладная логика требует 1 марта, это нужно запрограммировать отдельно.

Как вычесть год из даты?

Передайте отрицательное число месяцев: ДобавитьМесяц(Дата, -12). В запросе аналогично — ДОБАВИТЬКДАТЕ(Дата, ГОД, -1). Граничные случаи с 29 февраля обрабатываются тем же правилом последнего дня месяца.

Можно ли прибавить год прямо в формуле СКД?

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

Почему после добавления года сместилось время?

ДобавитьМесяц сохраняет время исходной даты. Если время сместилось, вероятно, дата вычислялась арифметикой секунд или смешивались клиентское и серверное время. Замените расчёт на ДобавитьМесяц и используйте ТекущаяДатаСеанса в серверном коде.

Как прибавить год к дате в формате строки?

Сначала преобразуйте строку в тип Дата функцией Дата() (для строк вида «ГГГГММДД») или через форматирование, затем применяйте ДобавитьМесяц. Работать с датой как со строкой и менять символы года вручную нельзя — это ломается на високосных годах и границах месяцев.

Итог

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

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