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

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

Как получить последний день месяца в 1С

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

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

Основной инструмент — функция КонецМесяца(), которая принимает дату и возвращает дату последнего дня того месяца, в который попадает переданное значение, со временем 23:59:59. Это важная деталь: функция возвращает не просто дату, а конкретный момент времени в конце суток, что удобно для сравнений и границ периодов.

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

Функция КонецМесяца: синтаксис и поведение

Функция доступна во встроенном языке 1С:Предприятия на тонком, толстом и веб-клиенте, а также на сервере. Синтаксис предельно прост: КонецМесяца(Дата), где параметр — значение типа Дата. Результат — тоже значение типа Дата, но со временем, установленным на 23:59:59 последнего дня месяца.

Пример базового использования:

ДатаОтчета = Дата(2026, 2, 15);

ПоследнийДень = КонецМесяца(ДатаОтчета);

// Результат: 29.02.2026 23:59:59

Обратите внимание на пример: февраль 2026 года — високосный, и функция корректно вернула 29 февраля. Функция самостоятельно учитывает високосные годы и разную длину месяцев, поэтому ручная логика вида «если месяц равен 2, то дней 28» не требуется и только создаёт источник ошибок.

Если передать в функцию текущую дату сеанса, получите конец текущего месяца:

КонецТекущегоМесяца = КонецМесяца(ТекущаяДатаСеанса());

Получение последнего дня произвольного месяца

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

// Конец предыдущего месяца

КонецПрошлогоМесяца = КонецМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -1));

// Конец следующего месяца

КонецСледующегоМесяца = КонецМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), 1));

Если известны только год и номер месяца (например, из настроек отчёта), сначала соберите любую дату внутри этого месяца, а затем примените функцию:

Год = 2026;

НомерМесяца = 11;

ДатаВнутриМесяца = Дата(Год, НомерМесяца, 1);

ПоследнийДень = КонецМесяца(ДатаВнутриМесяца);

// Результат: 30.11.2026 23:59:59

Порядок действий
  1. 1
    Определите дату, попадающую в нужный месяц (текущая дата, параметр отчёта или дата документа)
  2. 2
    При необходимости сместите её функцией ДобавитьМесяц() на нужное количество месяцев
  3. 3
    Примените КонецМесяца() к полученной дате
  4. 4
    Проверьте результат в отладчике: день должен быть последним, время — 23:59:59

Последний день месяца в запросах

В языке запросов 1С функция КонецМесяца() недоступна — вместо неё используется конструкция работы с периодами КОНЕЦПЕРИОДА. Она принимает два параметра: дату и тип периода.

ВЫБРАТЬ

КОНЕЦПЕРИОДА(&Дата, МЕСЯЦ) КАК ПоследнийДеньМесяца

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

Типовой сценарий — фильтрация документов или остатков по границе месяца. Здесь удобно передавать в запрос уже вычисленную дату параметром, а не вычислять её в тексте запроса, если дата используется несколько раз:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ПродажиОбороты.Номенклатура,

| ПродажиОбороты.КоличествоОборот

|ИЗ

| РегистрНакопления.Продажи.Обороты(, &КонецМесяца, , ) КАК ПродажиОбороты";

Запрос.УстановитьПараметр("КонецМесяца", КонецМесяца(ДатаОтчета));

Границы периода: почему важно время 23:59:59

Ключевая особенность результата — время 23:59:59. Именно поэтому КонецМесяца() корректно работает в сравнениях вида ДатаДокумента <= КонецМесяца(Период): документ, проведённый в любой момент последнего дня, попадёт в условие.

Типичная ошибка — сравнивать документы с датой, у которой время 00:00:00. Например, конструкция НачалоДня(КонецМесяца(Период)) вернёт последнее число месяца в полночь, и все документы, проведённые днём 30-го или 31-го числа, выпадут из выборки. В отчётах это проявляется как «потерянные» документы последнего дня месяца.

Если же вам нужна именно дата без времени (например, для вывода пользователю или сравнения по календарному дню), применяйте к результату НачалоДня() осознанно и только в месте отображения, а не в логике отбора:

ДатаДляПоказа = НачалоДня(КонецМесяца(Период)); // 30.11.2026 0:00:00
Типичные ошибки
01
Сравнение дат документов с датой 00:00:00 последнего дня — документы за последний день месяца теряются
02
Ручной расчёт числа дней в месяце через соответствие — ошибки в феврале високосного года
03
Использование КонецМесяца в тексте запроса — ошибка разбора, в запросах нужна КОНЕЦПЕРИОДА
04
Передача в функцию строки вместо типа Дата — ошибка преобразования типов

Альтернативные способы и когда они оправданы

Иногда встречается приём «первая дата следующего месяца минус секунда». Он даёт тот же результат, что и КонецМесяца(), но длиннее и менее читаем:

// Эквивалент КонецМесяца(Дата)

Результат = НачалоМесяца(ДобавитьМесяц(Дата, 1)) - 1;

Единственная ситуация, где такой приём имеет смысл — когда вам нужна граница «до начала следующего месяца» как открытый интервал, например ДатаДокумента < НачалоМесяца(СледующийМесяц). В остальных случаях используйте штатную функцию: она короче и понятнее при чтении кода.

Для получения номера последнего дня месяца как числа (28, 30, 31) без привязки к конкретной дате можно взять день от результата функции:

ЧислоДнейВМесяце = День(КонецМесяца(Дата(2026, 2, 1))); // 29

Этот приём полезен при расчёте пропорций, например при распределении ежемесячной суммы по дням или вычислении среднедневного значения.

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

КонецМесяца(Дата)

Основной способ во встроенном языке. Коротко, учитывает високосные годы, возвращает 23:59:59

КОНЕЦПЕРИОДА(Дата, МЕСЯЦ)

Единственный вариант внутри текста запроса. Поведение аналогично встроенной функции

НачалоМесяца(ДобавитьМесяц(Дата,1)) - 1

Даёт тот же результат, но громоздко. Оправдано только для открытых интервалов

Ручной расчёт по числу дней

Не рекомендуется: требует отдельной обработки февраля и високосных лет, легко ошибиться

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

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

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

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

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

ГраницаПериода = КонецМесяца(ДатаОтчета);

Иначе

ВызватьИсключение "Не указана дата отчёта";

КонецЕсли;

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

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

Время результата
Норма

23:59:59

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

00:00:00 — риск потери документов последнего дня

Февраль високосного года
Норма

29.02

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

28.02 — вероятно, ручной расчёт дней

Смещение через декабрь
Норма

Год увеличился, месяц = 01

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

Месяц 13 или ошибка преобразования

Тип параметра
Норма

Значение типа Дата

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

Строка, Неопределено — ошибка исполнения

Типовые сценарии применения

Отчёт за месяц

При формировании отчёта за месяц передайте в параметры виртуальной таблицы остатков или оборотов КонецМесяца(ДатаОтчета). Для регистров накопления это гарантирует, что в обороты попадут все движения последнего дня, включая вечерние.

Закрытие месяца и регламентные операции

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

Графики платежей и сроки оплаты

Если договор предусматривает оплату «до конца месяца», дата платежа вычисляется как КонецМесяца(ДатаОтгрузки). При выводе в печатную форму форматируйте значение через Формат(ДатаПлатежа, "ДЛФ=D"), чтобы время 23:59:59 не попало в документ.

Итог

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

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

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

Чем КонецМесяца отличается от НачалоДня(КонецМесяца)?

КонецМесяца возвращает последний день со временем 23:59:59, а обёртка НачалоДня сбрасывает время до 00:00:00. Для отборов по периоду используйте первый вариант, для отображения даты без времени — второй.

Как получить последний день месяца в запросе 1С?

Используйте конструкцию КОНЕЦПЕРИОДА(Дата, МЕСЯЦ). Она работает только в тексте запроса; в программном коде применяйте функцию КонецМесяца и передавайте результат параметром.

Учитывает ли функция високосный год?

Да. Для февраля високосного года КонецМесяца вернёт 29 февраля, для обычного — 28 февраля. Никакой дополнительной логики писать не нужно.

Как получить конец предыдущего месяца?

Скомбинируйте две функции: КонецМесяца(ДобавитьМесяц(Дата, -1)). Смещение через границу года обрабатывается корректно автоматически.

Почему в отчёт не попадают документы последнего дня месяца?

Скорее всего, в условии сравнения используется дата со временем 00:00:00 вместо 23:59:59. Замените границу на КонецМесяца(Период) или сравнивайте с началом следующего месяца через строгое неравенство.

Можно ли получить только номер последнего дня месяца как число?

Да: День(КонецМесяца(НужнаяДата)) вернёт число от 28 до 31. Это удобно для расчёта среднедневных значений и пропорций.