Разработка и Конфигурация · 9 мин
Как в 1С из даты вычесть месяц
Как в 1С вычесть месяц из даты: функция ДобавитьМесяц с отрицательным значением, примеры кода, нюансы конца месяца, запросы и типичные ошибки.
Задача вычесть месяц из даты встречается в 1С постоянно: расчёт периодов отчётности, определение даты начала прошлого месяца, сроки оплаты, отложенные проверки. Встроенного оператора «минус месяц» во встроенном языке нет — вычитание числа из даты сдвигает её на секунды, а не на календарные месяцы. Для работы с месяцами предназначена функция ДобавитьМесяц(), которая при отрицательном аргументе работает как вычитание.
Главная тонкость — календарная логика. Месяцы имеют разную длину, поэтому «минус месяц» от 31 марта не может дать 31 февраля. Функция решает это по правилу: если в целевом месяце нет такого числа, результатом становится последний день этого месяца. Понимание этого правила избавляет от большинства ошибок в расчётах периодов.
Ниже разобраны синтаксис функции, готовые примеры кода, поведение на границах месяца и года, аналог для языка запросов и типичные ошибки, которые приводят к неверным датам в документах и отчётах.
Функция ДобавитьМесяц: синтаксис и принцип работы
Функция ДобавитьМесяц() доступна во встроенном языке 1С:Предприятие 8 на тонком, толстом и веб-клиенте, а также на сервере. Она принимает два параметра: исходную дату и количество месяцев, которое нужно добавить. Для вычитания передаётся отрицательное число.
НоваяДата = ДобавитьМесяц(ИсходнаяДата, -1);
Функция возвращает значение типа Дата. Время суток (часы, минуты, секунды) сохраняется без изменений: если исходная дата была 15.03.2026 14:30:00, то результат вычитания месяца — 15.02.2026 14:30:00. Это важно, если дальше дата сравнивается с границами периода, где время имеет значение.
Если передать ноль, функция вернёт исходную дату без изменений. Если передать нецелое число, дробная часть отбрасывается — полагаться на это не стоит, лучше явно приводить параметр к целому через Цел() или Окр().
Готовые примеры кода
Базовый сценарий — вычесть один месяц из текущей даты:
ТекущаяДата = ТекущаяДатаСеанса();
МесяцНазад = ДобавитьМесяц(ТекущаяДата, -1);
Вычитание произвольного количества месяцев, например квартала (3 месяца) или года (12 месяцев):
ДатаОтсчета = '20260715';
ТриМесяцаНазад = ДобавитьМесяц(ДатаОтсчета, -3); // 15.04.2026
ГодНазад = ДобавитьМесяц(ДатаОтсчета, -12); // 15.07.2023
Типовая практическая задача — получить первое число прошлого месяца. Здесь вычитание месяца комбинируется с функцией НачалоМесяца():
ПервоеЧислоПрошлогоМесяца = НачалоМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -1));
Аналогично получают конец прошлого месяца — сочетанием КонецМесяца() и ДобавитьМесяц(). Такая пара функций покрывает почти все потребности отчётных периодов: «прошлый месяц», «позапрошлый месяц», «тот же месяц год назад».
// Вычесть один месяц из даты
ДатаМесяцНазад = ДобавитьМесяц(ИсходнаяДата, -1);
// Период прошлого месяца целиком
НачалоПериода = НачалоМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -1));
КонецПериода = КонецМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -1));Граничные случаи: конец месяца и переход через год
Самое частое удивление у разработчиков вызывает поведение функции на датах вроде 31 марта. Вычитание месяца из 31.03.2026 даёт 29.02.2026, а не 31 февраля — такого дня не существует. Функция берёт последний доступный день целевого месяца. В невисокосный год результатом будет 28 февраля.
Аналогично 31 мая минус месяц даёт 30 апреля, а 31 января минус месяц — 31 декабря прошлого года. Переход через границу года обрабатывается автоматически, отдельный код для смены года не нужен.
03.2026, а не 31.03.2026. Если бизнес-логика требует «тот же день месяца или последний», такое поведение корректно, но при строгих требованиях к датам (например, графики платежей) результат нужно дополнительно проверять или нормализовать через КонецМесяца().
Вычитание месяца в запросах
В языке запросов 1С есть своя функция — ДОБАВИТЬКДАТЕ(). Она принимает дату, тип смещения (СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД) и величину смещения. Для вычитания месяца величина указывается отрицательной:
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(РеализацияТоваровУслуг.Дата, МЕСЯЦ, -1) КАК ДатаМесяцНазад
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
Частый сценарий — отбор документов за последний месяц относительно параметра:
ГДЕ
Документ.Дата МЕЖДУ ДОБАВИТЬКДАТЕ(&ТекущаяДата, МЕСЯЦ, -1) И &ТекущаяДата
Учтите, что ДОБАВИТЬКДАТЕ выполняется на сервере СУБД, и поведение на границах месяца может незначительно отличаться в зависимости от используемой СУБД. Если точность граничных дат критична, результат запроса стоит проверить на тестовых данных с датами 29–31 числа.
Где вычитать месяц
Подходит для алгоритмов, проведения документов, обработок. Гибко комбинируется с НачалоМесяца и КонецМесяца.
Подходит для отборов и вычисляемых полей прямо в запросе, без выгрузки данных в код. Эффективнее при больших объёмах.
Не рекомендуется: месяц не имеет фиксированной длительности, результат будет неверным на большинстве дат.
Типовые сценарии в прикладных решениях
Период прошлого месяца для отчёта
Когда пользователь открывает отчёт, удобно по умолчанию подставлять прошлый месяц. Для этого в событии формы вычисляются обе границы через ДобавитьМесяц() и функции начала/конца месяца. Такой подход гарантирует, что период всегда полный, без обрезанных первого и последнего дня.
Срок оплаты и отложенные события
В договорах с отсрочкой «один месяц с даты отгрузки» дату оплаты вычисляют как ДобавитьМесяц(ДатаОтгрузки, 1), а для контрольных уведомлений «за месяц до события» — с параметром -1. Здесь важно зафиксировать в требованиях, как трактуется 31-е число, чтобы правило было одинаковым во всех документах.
Закрытие периода и регламентные операции
В регламентных заданиях, обрабатывающих «предыдущий месяц», дату вычисляют от ТекущаяДатаСеанса(), а не от ТекущаяДата() клиента — иначе при разных часовых поясах пользователей период может сместиться. Это особенно важно в распределённых базах и филиальных структурах.
- 1Определите исходную дату: параметр, реквизит документа или ТекущаяДатаСеанса().
- 2Вызовите ДобавитьМесяц(ИсходнаяДата, -1) для сдвига на месяц назад.
- 3При необходимости нормализуйте результат через НачалоМесяца() или КонецМесяца().
- 4Проверьте результат на граничной дате, например 31 марта, чтобы убедиться в корректности логики.
Проверка результата и типичные ошибки
Проверять расчёт удобнее всего на наборе «опасных» дат: 31 января, 31 марта, 29 февраля високосного года, 1 января. Для каждой даты результат вычитания месяца должен соответствовать ожиданиям бизнес-логики. Если правило «последний день месяца» неприемлемо, добавьте явную обработку: сравнивайте день исходной и итоговой даты и при расхождении применяйте нужное правило.
Ещё одна проверка — тип значения. Если в переменной вместо даты оказалась строка или Неопределено, функция вызовет ошибку. Перед вызовом полезно убедиться, что значение заполнено, особенно когда дата приходит из реквизита, который пользователь мог не заполнить.
Как проверить результат
29.02.2026 — последний день февраля високосного года
Ошибка или дата в марте
01.12.2023 — корректный переход через год
Дата осталась в том же году
Часы, минуты и секунды совпадают с исходной датой
Время обнулилось или изменилось
Частые вопросы
Можно ли вычесть месяц простым вычитанием числа из даты?
Нет. Вычитание числа из даты в 1С сдвигает её на указанное количество секунд. Например, Дата - 30 24 60 * 60 сдвинет дату примерно на 30 дней, но месяц не равен 30 дням, поэтому для календарных месяцев нужна функция ДобавитьМесяц() с отрицательным параметром.
Что вернёт ДобавитьМесяц от 31 марта с параметром -1?
Последний день февраля: 29 февраля в високосный год и 28 февраля в обычный. Функция не может вернуть несуществующую дату «31 февраля» и округляет результат до последнего дня целевого месяца.
Как получить первое число прошлого месяца?
Комбинацией двух функций: НачалоМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -1)). Сначала дата сдвигается на месяц назад, затем берётся начало этого месяца. Аналогично для последнего дня используется КонецМесяца().
Как вычесть месяц в запросе 1С?
Используйте функцию языка запросов ДОБАВИТЬКДАТЕ(Дата, МЕСЯЦ, -1). Она работает и в выборке полей, и в условиях ГДЕ, что удобно для отбора документов за последний месяц без обработки данных в коде.
Сохраняется ли время при вычитании месяца?
Да, ДобавитьМесяц() сохраняет время суток исходной даты без изменений. Если для сравнения периодов время должно быть сброшено, дополнительно примените НачалоДня() или НачалоМесяца() к результату.
Как вычесть несколько месяцев, например квартал?
Передайте нужное отрицательное число вторым параметром: ДобавитьМесяц(Дата, -3) вычтет три месяца, ДобавитьМесяц(Дата, -12) — год. Отдельной функции для кварталов во встроенном языке нет, в запросе можно использовать тип смещения КВАРТАЛ.
Что важно запомнить
Месяц из даты в 1С вычитается функцией ДобавитьМесяц(Дата, -1), в запросах — ДОБАВИТЬКДАТЕ(Дата, МЕСЯЦ, -1). Функция корректно обрабатывает переход через год и разную длину месяцев, округляя несуществующие даты до последнего дня месяца. Вычитание секунд для этой задачи использовать нельзя.