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

Разработка и Конфигурация · 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С всегда выражается в секундах, поэтому деление обязательно. Этот способ длиннее, но полезен, когда нужно посчитать дни в произвольном интервале, а не только в календарном месяце.

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

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

Самый короткий и читаемый вариант. Подходит для всех задач, где нужен именно календарный месяц. Ограничений нет.

Разность начал месяцев / 86400

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

Язык запросов

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

Подсчёт дней в месяце в запросе

Когда количество дней нужно внутри запроса — например, для расчёта среднедневного заработка или нормы времени в отчёте, — используют функции языка запросов КОНЕЦПЕРИОДА и ДЕНЬ:

ВЫБРАТЬ

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

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

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

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

Расчёт оклада за неполный месяц

Типовая задача зарплатного учёта: сотрудник принят 15-го числа, нужно начислить оклад пропорционально. Формула использует количество календарных или рабочих дней месяца как знаменатель:

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

Начислено = Оклад * ОтработаноДней / ДнейВМесяце;

В типовых конфигурациях вроде «1С:Зарплата и управление персоналом» норма дней обычно берётся из графика работы, а не из календарной длины месяца. Прямой расчёт через КонецМесяца уместен в самописных механизмах и простых пропорциях.

Начисление аренды и абонентских платежей

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

Валидация введённой даты

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

Порядок действий
  1. 1
    Определите, от какой даты считается месяц: текущая дата, реквизит документа или параметр отчёта.
  2. 2
    Напишите выражение День(КонецМесяца(Дата)) или вынесите его в отдельную функцию общего модуля.
  3. 3
    Если расчёт нужен в выборке, перенесите логику в запрос: ДЕНЬ(КОНЕЦПЕРИОДА(&Период, МЕСЯЦ)).
  4. 4
    Проверьте результат на феврале високосного и невисокосного года, а также на месяцах с 30 и 31 днём.
  5. 5
    Убедитесь, что в расчётах не смешиваются календарные дни и дни по производственному графику.

Типичные ошибки и ограничения

Самая частая ошибка — передача в функции не даты, а строки или числа. Выражение КонецМесяца("01.02.2026") вызовет ошибку исполнения, потому что функция ожидает значение типа «Дата». Реквизиты, считанные из текста или из Excel, сначала преобразуют через Дата() или функции разбора строк.

Вторая группа ошибок связана со смешением понятий. Календарное количество дней месяца — это не количество рабочих дней и не количество дней по графику сотрудника. Для нормы рабочего времени в типовых решениях используют регистры графиков и производственные календари, а не арифметику дат.

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

Типичные ошибки
01
Передача строки вместо даты в КонецМесяца — ошибка исполнения или неверный результат.
02
Использование календарной длины месяца там, где нужна норма рабочих дней по графику — искажение начислений.
03
Забытое деление на 86400 при расчёте через разность дат — результат в секундах вместо дней.
04
Захардкоженная таблица длин месяцев без учёта високосного февраля — сбой раз в четыре года.

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

Перед внедрением расчёта в рабочую базу прогоните функцию на контрольном наборе дат: февраль високосного года (должно быть 29), февраль обычного года (28), апрель (30), январь (31). Четыре проверки покрывают все варианты длин месяцев.

Дополнительно убедитесь, что функция ведёт себя стабильно на граничных значениях: первое и последнее число месяца, даты с ненулевым временем. КонецМесяца игнорирует время входной даты, поэтому 01.03.2026 00:00:00 и 31.03.2026 18:45:12 дадут одинаковый результат — 31.

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

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

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

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

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

Возвращает 28 — где-то потерян високосный год

Месяц с 30 днями (апрель, июнь, сентябрь, ноябрь)
Норма

Возвращает 30

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

Возвращает 31 — вероятно, используется фиксированная таблица с ошибкой

Тип входного значения
Норма

Передаётся значение типа Дата

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

Передаётся строка или число — нужна явная конвертация

Расчёт в запросе
Норма

ДЕНЬ(КОНЕЦПЕРИОДА(&Период, МЕСЯЦ)) даёт число от 28 до 31

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

Результат в секундах или пустое значение

Итог

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

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

Частые вопросы

Есть ли в 1С готовая функция «КоличествоДнейВМесяце»?

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

Как учесть високосный год при подсчёте дней февраля?

Отдельно учитывать его не нужно. Функция КонецМесяца сама определяет последний день февраля по календарным правилам и вернёт 28 или 29 февраля в зависимости от года. Ручная проверка високосности требуется только для специфических алгоритмов, не связанных с длиной месяца.

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

Вычтите одну дату из другой и разделите результат на 86400, так как разность дат в 1С выражается в секундах. Для включения обеих граничных дат в интервал добавьте к результату единицу.

Чем отличаются КонецМесяца и КонецПериода в запросе?

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

Почему КонецМесяца возвращает время 23:59:59 и влияет ли это на подсчёт дней?

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

Можно ли посчитать количество рабочих дней в месяце тем же способом?

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