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