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

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

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

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

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

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

Базовый способ: День(КонецМесяца(Дата))

Функция КонецМесяца(Дата) принимает значение типа Дата и возвращает дату последнего дня этого месяца со временем 23:59:59. Например, для 15.02.2026 она вернёт 29.02.2026 23:59:59. Затем функция День() извлекает из полученной даты номер дня — число от 1 до 31.

Пример кода для произвольной даты:

ДатаПроверки = Дата(2026, 2, 10);

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

// Результат: 29 (високосный год)

ДатаПроверки = Дата(2023, 2, 10);

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

// Результат: 28

Если нужно узнать количество дней в текущем месяце, передайте в качестве параметра текущую дату сеанса: День(КонецМесяца(ТекущаяДатаСеанса())). Важно использовать именно ТекущаяДатаСеанса(), а не устаревшее ТекущаяДата(), чтобы на сервере и клиенте не возникало расхождений из-за разных часовых поясов.

1c
КоличествоДней = День(КонецМесяца(ТекущаяДатаСеанса()));

Оформление универсальной функции

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

Пример оформления:

// Возвращает количество дней в месяце указанной даты.

//

// Параметры:

// Период - Дата - любая дата внутри нужного месяца.

//

// Возвращаемое значение:

// Число - количество дней в месяце (28–31).

//

Функция КоличествоДнейВМесяце(Период) Экспорт

Возврат День(КонецМесяца(Период));

КонецФункции

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

Получение количества дней в запросе

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

ВЫБРАТЬ

Начисления.Период КАК Период,

ДЕНЬ(КОНЕЦПЕРИОДА(Начисления.Период, МЕСЯЦ)) КАК ДнейВМесяце,

Начисления.Сумма КАК Сумма

ИЗ

РегистрНакопления.Начисления КАК Начисления

Такой подход удобен, когда количество дней нужно сразу для большого набора строк: вычисление происходит на уровне СУБД и не требует обхода выборки в коде. Альтернатива — вычисляемое поле в СКД с тем же выражением, если отчёт строится на компоновке данных.

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

День(КонецМесяца(Дата)) в коде

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

ДЕНЬ(КОНЕЦПЕРИОДА(..., МЕСЯЦ)) в запросе

Оптимально для массовых расчётов по выборке и в СКД. Требует аккуратности с типом поля — работает только с датами.

Производственный календарь

Нужен, если требуются не календарные, а рабочие дни. Даёт точные данные с учётом праздников, но зависит от актуальности заполнения календаря.

Количество рабочих дней по производственному календарю

Календарное количество дней подходит не всегда. Для расчёта зарплаты, норм времени и графиков обычно нужны рабочие дни с учётом праздников и переносов. В типовых конфигурациях (ЗУП, ERP, Бухгалтерия) для этого служит регистр сведений «Данные производственного календаря» и готовые функции из общих модулей, например КалендарныеГрафики в библиотеке стандартных подсистем.

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

Типичные ошибки и как их избежать

Первая частая ошибка — жёсткое кодирование количества дней через соответствие или конструкцию Если Месяц = 2 Тогда .... Такой код неизбежно ломается на високосных годах или требует отдельной проверки делимости года, которую легко реализовать с ошибкой. Встроенные функции платформы решают это корректно всегда.

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

Третья ошибка — использование КонецМесяца там, где нужен конец дня последнего дня для условий ГДЕ. Для границ периодов в запросах корректнее применять КОНЕЦПЕРИОДА или виртуальные таблицы с параметрами, а не вычислять дату вручную вычитанием секунд.

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

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

Проверить корректность вычисления можно в нескольких контрольных точках. Февраль високосного года должен давать 29, обычного — 28. Апрель, июнь, сентябрь и ноябрь — 30, остальные месяцы — 31. Прогоните функцию по всем двенадцати месяцам пары лет (високосного и обычного) в консоли кода или тестовой обработке.

Отдельно проверьте поведение при пустой дате. КонецМесяца(Дата(1,1,1)) вернёт 31.01.0001, и функция выдаст 31 — формально корректно, но в бизнес-логике пустая дата обычно означает ошибку входных данных. Если параметр может быть не заполнен, добавьте явную проверку ЗначениеЗаполнено(Период) и осмысленную реакцию: возврат нуля или вызов исключения.

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

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

Февраль високосного года (например, дата в феврале 2026)
Норма

Функция возвращает 29

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

Возвращает 28 — вероятно, где-то используется жёсткая таблица месяцев

Февраль обычного года
Норма

Функция возвращает 28

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

Возвращает 29 или 30 — ошибка в логике определения месяца

Пустая дата (01.01.0001)
Норма

Код явно обрабатывает ситуацию: проверка заполненности до вычисления

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

Функция молча возвращает 31, и это число уходит в расчёты

Месяцы по 31 дню (январь, март и т.д.)
Норма

Возвращается 31

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

Возвращается 30 — признак ручного соответствия с ошибкой

Практические сценарии применения

Расчёт пропорции отработанного времени

Типичный сценарий — расчёт суммы пропорционально дням: СуммаПропорционально = МесячнаяСтавка / ДнейВМесяце * ОтработаноДней. Здесь количество дней в месяце выступает знаменателем, и его корректность напрямую влияет на результат. Деление выполняйте с контролем нуля, если дата может быть не заполнена.

Проверка корректности введённой даты

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

Формирование графика платежей

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

Итог

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

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

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

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

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

Работает ли КонецМесяца на клиенте в управляемых формах?

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

Чем КонецМесяца отличается от вычитания секунды из начала следующего месяца?

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

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

Разность дат в 1С даёт результат в секундах, поэтому количество дней считают как (ДатаОкончания - ДатаНачала) / 86400. Для включения обеих граничных дат в интервал добавьте единицу к результату.

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

Да, добавьте вычисляемое поле в настройках компоновки с выражением на языке выражений СКД. Если поле даты доступно в наборе данных, выражение День(КонецПериода(ПолеДаты, "Месяц")) или аналогичная конструкция через функции запроса в наборе данных решит задачу без доработки основного запроса.

Почему функция возвращает 31 для пустой даты?

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