Разработка и Конфигурация · 9 мин
Как посчитать количество дней в месяце в 1С
Способы посчитать количество дней в месяце в 1С: функция День(КонецМесяца()), запросы, разница дат. Примеры кода, ошибки, FAQ для разработчика 1С.
Задача определить, сколько дней в конкретном месяце, возникает в 1С постоянно: при расчёте оклада пропорционально отработанным дням, при начислении аренды, при формировании производственных календарей, при проверке дат в документах. Встроенный язык 1С не содержит функции «КоличествоДнейВМесяце», поэтому значение получают через комбинацию стандартных функций работы с датами.
Самый надёжный способ — взять конец месяца функцией КонецМесяца() и извлечь из полученной даты номер дня функцией День(). Поскольку конец месяца всегда приходится на его последнее число (28, 29, 30 или 31), номер этого дня и есть искомое количество дней. Такой подход автоматически учитывает високосные годы и не требует ручных таблиц длин месяцев.
Ниже разобраны рабочие варианты кода, способ через запрос, типичные ошибки с типами данных и проверка результата. Все примеры применимы к типовым конфигурациям и самописным решениям на платформе 1С:Предприятие 8.3.
Основной способ: День(КонецМесяца(Дата))
Функция КонецМесяца(Дата) возвращает дату последнего дня месяца со временем 23:59:59. Например, для 15.02.2026 она вернёт 29.02.2026 23:59:59, поскольку 2026 год високосный. Функция День() извлекает из этой даты номер дня — 29.
Готовая функция для общего модуля выглядит так:
Функция КоличествоДнейВМесяце(Дата) Экспорт
Возврат День(КонецМесяца(Дата));
КонецФункции
Вызов в любом месте кода:
ДнейВФеврале = КоличествоДнейВМесяце(Дата(2026, 2, 10)); // 29
ДнейВАпреле = КоличествоДнейВМесяце(Дата(2026, 4, 1)); // 30
ДнейВЯнваре = КоличествоДнейВМесяце(ТекущаяДата()); // зависит от текущего месяца
Проверка високосного года и альтернативный расчёт
Если по какой-то причине нужно определить високосность отдельно, её проверяют арифметикой: год високосный, когда он делится на 4, но не делится на 100, либо делится на 400. Однако для подсчёта дней в феврале эта логика не нужна — КонецМесяца уже учитывает календарные правила.
Альтернативный приём — вычесть из первого дня следующего месяца один день или посчитать разность дат:
ПервоеЧислоСледующего = НачалоМесяца(ДобавитьМесяц(Дата, 1));
КоличествоДней = (ПервоеЧислоСледующего - НачалоМесяца(Дата)) / 86400;
Здесь 86400 — число секунд в сутках. Разность двух дат в 1С всегда выражается в секундах, поэтому деление обязательно. Этот способ длиннее, но полезен, когда нужно посчитать дни в произвольном интервале, а не только в календарном месяце.
Сравнение вариантов
Самый короткий и читаемый вариант. Подходит для всех задач, где нужен именно календарный месяц. Ограничений нет.
Универсален для произвольных периодов, но требует аккуратности с секундами и больше кода.
Оптимален, когда количество дней нужно прямо в выборке для группировки или расчёта в отчёте, без обхода результатов.
Подсчёт дней в месяце в запросе
Когда количество дней нужно внутри запроса — например, для расчёта среднедневного заработка или нормы времени в отчёте, — используют функции языка запросов КОНЕЦПЕРИОДА и ДЕНЬ:
ВЫБРАТЬ
ДЕНЬ(КОНЕЦПЕРИОДА(&Период, МЕСЯЦ)) КАК ДнейВМесяце
Параметр &Период передаётся как дата любого дня нужного месяца. Результат — число от 28 до 31, которое можно использовать в выражениях, соединениях и итогах.
Для таблицы с несколькими месяцами удобно сгруппировать по началу периода и вычислить длину каждого месяца одним запросом, не выгружая данные в обход. Это заметно быстрее на больших выборках, чем построчный расчёт в коде.
Практические сценарии применения
Расчёт оклада за неполный месяц
Типовая задача зарплатного учёта: сотрудник принят 15-го числа, нужно начислить оклад пропорционально. Формула использует количество календарных или рабочих дней месяца как знаменатель:
ДнейВМесяце = День(КонецМесяца(ПериодРасчета));
Начислено = Оклад * ОтработаноДней / ДнейВМесяце;
В типовых конфигурациях вроде «1С:Зарплата и управление персоналом» норма дней обычно берётся из графика работы, а не из календарной длины месяца. Прямой расчёт через КонецМесяца уместен в самописных механизмах и простых пропорциях.
Начисление аренды и абонентских платежей
При помесячной тарификации услуг стоимость дня определяется как цена месяца, делённая на его фактическую длину. Тогда первый и последний неполные месяцы договора рассчитываются корректно: февраль с 28 днями и июль с 31 днём дадут разную дневную ставку, что соответствует условиям большинства договоров.
Валидация введённой даты
Если пользователь вводит день, месяц и год отдельными полями, количество дней месяца служит верхней границей проверки: для февраля нельзя принять значение 30. Сравнение с День(КонецМесяца(СобраннаяДата)) отсекает несуществующие даты до записи в базу.
- 1Определите, от какой даты считается месяц: текущая дата, реквизит документа или параметр отчёта.
- 2Напишите выражение День(КонецМесяца(Дата)) или вынесите его в отдельную функцию общего модуля.
- 3Если расчёт нужен в выборке, перенесите логику в запрос: ДЕНЬ(КОНЕЦПЕРИОДА(&Период, МЕСЯЦ)).
- 4Проверьте результат на феврале високосного и невисокосного года, а также на месяцах с 30 и 31 днём.
- 5Убедитесь, что в расчётах не смешиваются календарные дни и дни по производственному графику.
Типичные ошибки и ограничения
Самая частая ошибка — передача в функции не даты, а строки или числа. Выражение КонецМесяца("01.02.2026") вызовет ошибку исполнения, потому что функция ожидает значение типа «Дата». Реквизиты, считанные из текста или из Excel, сначала преобразуют через Дата() или функции разбора строк.
Вторая группа ошибок связана со смешением понятий. Календарное количество дней месяца — это не количество рабочих дней и не количество дней по графику сотрудника. Для нормы рабочего времени в типовых решениях используют регистры графиков и производственные календари, а не арифметику дат.
Третья ловушка — использование конца месяца в границах периодов без учёта времени 23:59:59. Если сравнивать документы условием «ДатаДокумента <= КонецМесяца(Период)», документ с временем 23:59:59 последнего дня попадёт в выборку, а при сравнении с НачалоДня следующего месяца логика уже другая. Выбирайте границы осознанно.
Проверка корректности результата
Перед внедрением расчёта в рабочую базу прогоните функцию на контрольном наборе дат: февраль високосного года (должно быть 29), февраль обычного года (28), апрель (30), январь (31). Четыре проверки покрывают все варианты длин месяцев.
Дополнительно убедитесь, что функция ведёт себя стабильно на граничных значениях: первое и последнее число месяца, даты с ненулевым временем. КонецМесяца игнорирует время входной даты, поэтому 01.03.2026 00:00:00 и 31.03.2026 18:45:12 дадут одинаковый результат — 31.
Как проверить результат
Функция возвращает 29
Возвращает 28 — где-то потерян високосный год
Возвращает 30
Возвращает 31 — вероятно, используется фиксированная таблица с ошибкой
Передаётся значение типа Дата
Передаётся строка или число — нужна явная конвертация
ДЕНЬ(КОНЕЦПЕРИОДА(&Период, МЕСЯЦ)) даёт число от 28 до 31
Результат в секундах или пустое значение
Что важно запомнить
Количество дней в месяце в 1С получают выражением День(КонецМесяца(Дата)) в коде и ДЕНЬ(КОНЕЦПЕРИОДА(&Период, МЕСЯЦ)) в запросах. Оба способа автоматически учитывают високосные годы. Не путайте календарную длину месяца с нормой рабочих дней по графику и всегда проверяйте тип входного значения.
Частые вопросы
Есть ли в 1С готовая функция «КоличествоДнейВМесяце»?
Во встроенном языке такой функции нет. Стандартный приём — День(КонецМесяца(Дата)). В некоторых типовых конфигурациях и библиотеке стандартных подсистем есть похожие сервисные функции в общих модулях работы с датами, но их наличие зависит от конкретной конфигурации.
Как учесть високосный год при подсчёте дней февраля?
Отдельно учитывать его не нужно. Функция КонецМесяца сама определяет последний день февраля по календарным правилам и вернёт 28 или 29 февраля в зависимости от года. Ручная проверка високосности требуется только для специфических алгоритмов, не связанных с длиной месяца.
Как посчитать количество дней между двумя датами, а не в месяце?
Вычтите одну дату из другой и разделите результат на 86400, так как разность дат в 1С выражается в секундах. Для включения обеих граничных дат в интервал добавьте к результату единицу.
Чем отличаются КонецМесяца и КонецПериода в запросе?
Это аналоги для разных контекстов: КонецМесяца работает во встроенном языке, КОНЕЦПЕРИОДА(Дата, МЕСЯЦ) — в языке запросов. Обе возвращают последний момент месяца, из которого функцией День или ДЕНЬ извлекается номер последнего дня.
Почему КонецМесяца возвращает время 23:59:59 и влияет ли это на подсчёт дней?
Такое время гарантирует, что в период попадают все события последнего дня. На подсчёт количества дней это не влияет — функция День берёт только календарный номер. Время важно учитывать лишь при сравнениях дат и построении границ отборов.
Можно ли посчитать количество рабочих дней в месяце тем же способом?
Нет. День(КонецМесяца(Дата)) даёт только календарные дни. Рабочие дни определяются по производственному календарю или графику работы: в типовых конфигурациях для этого используются соответствующие регистры сведений и функции общих модулей календарных графиков.