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

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

1. Стандартные функции 1С для работы с датами

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

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

КоличествоДней = ДнейВМесяце(Дата(2026, 2, 1)); // Вернёт 29 (високосный февраль)

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

  • Плюсы: Простота, надёжность, нет зависимости от конфигурации.
  • ⚠️ Минусы: Требует передачи полноценной даты (нельзя указать только месяц и год).
  • 🔄 Альтернатива: Функция КонецМесяца() + вычитание начала месяца (разберём ниже).
💡

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

2. Использование функции КонецМесяца()

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

ПервыйДень = НачалоМесяца(Дата(2026, 4, 1));

ПоследнийДень = КонецМесяца(Дата(2026, 4, 1));

КоличествоДней = ПоследнийДень - ПервыйДень + 1; // Вернёт 30 (апрель)

Этот метод универсален и работает даже в старых версиях платформы (включая 1С 7.7, если требуется обратная совместимость). Его часто используют в отчётах, где нужно динамически определять границы периода. Например, при формировании данных за "полный месяц" независимо от текущей даты.

⚠️ Внимание: Если вы работаете с неполными месяцами (например, при расчёте зарплаты за период с 15 числа), этот метод даст количество дней в полном календарном месяце, а не в вашем рабочем периоде. Для таких случаев потребуется дополнительная логика.
Функция Пример использования Результат для февраля 2026
ДнейВМесяце() ДнейВМесяце(Дата(2026, 2, 1)) 29
КонецМесяца() КонецМесяца(Дата(2026, 2, 1)) - Дата(2026, 2, 1) + 1 29
ДобавитьМесяц() + вычитание ДобавитьМесяц(Дата(2026, 2, 1), 1) - Дата(2026, 2, 1) 29

3. Программный код: универсальная функция

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

Функция ПолучитьКоличествоДнейВМесяце(Год, Месяц)

// Проверяем корректность входных данных

Если Год < 1 Или Месяц < 1 Или Месяц > 12 Тогда

Возврат 0;

КонецЕсли;

// Создаём дату на основе переданных параметров

ДатаНачала = Дата(Год, Месяц, 1);

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

Возврат ПоследнийДень.День();

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

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

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

Если Дата(2026, 1, 1).ВисокосныйГод() Тогда

// Логика для високосного года

КонецЕсли;

- Указать несуществующий месяц (13) → должен вернуть 0

- Передать февраль 2026 года → должен вернуть 29

- Проверить апрель 2023 года → должен вернуть 30

- Указать год 0 или отрицательный → должен вернуть 0

-->

4. Работа с запросами 1С

В некоторых случаях количество дней в месяце требуется определить непосредственно в тексте запроса 1С. Например, при формировании отчётов с группировкой по месяцам или расчёте средних значений. Для этого можно использовать конструкцию с ВЫБОР и встроенными функциями дат.

Пример запроса, который возвращает количество дней для каждого месяца в заданном диапазоне:

ВЫБРАТЬ

Год(ДатаНачала) КАК Год,

Месяц(ДатаНачала) КАК Месяц,

ДнейВМесяце(ДатаНачала) КАК КоличествоДней

ИЗ

Календарь КАК Календарь

ГДЕ

Календарь.ДатаНачала МЕЖДУ &НачалоПериода И &КонецПериода

УПОРЯДОЧИТЬ ПО

Год, Месяц

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

⚠️ Внимание: В запросах функция ДнейВМесяце() работает только с полями типа Дата. Если вы передаёте строку или число, получите ошибку. Всегда проверяйте типы данных перед использованием.
  • 📅 Сценарий 1: Отчёт по продажам с нормированием на количество дней в месяце.
  • 📊 Сценарий 2: Аналитика посещаемости (например, среднее число клиентов в день).
  • 💰 Сценарий 3: Расчёт премий сотрудников с учётом отработанных дней.

5. Календарные методы и внешние обработки

Если ваша конфигурация интегрирована с внешними системами или использует специализированные обработки (например, для управления проектами или производственным календарём), количество дней в месяце может зависеть от производственного календаря. В этом случае стандартные функции платформы дадут календарное значение, а не фактическое количество рабочих дней.

Для учёта праздников и выходных используйте:

  • 📅 Производственный календарь 1С: В типовой конфигурации Зарплата и Управление Персоналом есть справочник с официальными праздничными днями. Можно написать функцию, которая вычитает выходные и праздники из общего количества дней.
  • 🔄 Внешние обработки: Например, обработка "Календарь.epf" (доступна на Инфостарте) позволяет гибко настраивать рабочие дни и автоматически рассчитывать их количество.
  • 📎 Интеграция с API: Если ваша система синхронизирована с Google Calendar или Outlook, можноpull данные о рабочих днях оттуда.

Пример кода для расчёта рабочих дней (без учёта праздников):

Функция ПолучитьРабочиеДниВМесяце(Год, Месяц)

КоличествоДней = ДнейВМесяце(Дата(Год, Месяц, 1));

РабочиеДни = 0;

Для Счётчик = 1 По КоличествоДней Цикл

ТекущаяДата = Дата(Год, Месяц, Счётчик);

Если НЕ ТекущаяДата.ДеньНедели() = 6 И НЕ ТекущаяДата.ДеньНедели() = 7 Тогда // 6 и 7 - суббота и воскресенье

РабочиеДни = РабочиеДни + 1;

КонецЕсли;

КонецЦикла;

Возврат РабочиеДни;

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

Как учесть праздничные дни?

Для полного учёта праздников нужно интегрироваться со справочником "ПроизводственныйКалендарь" (если он есть в конфигурации) или загружать данные из внешнего источника. В типовой "ЗУП" это реализовано через механизм графиков работы. Например, можно использовать такой код:

ПроизводственныйКалендарь = Справочники.ПроизводственныйКалендарь.НайтиПоНаименованию("Основной");

Если ПроизводственныйКалендарь.ПраздничныеДни.Найти(ТекущаяДата) <> Неопределён Тогда

// День является праздничным

КонецЕсли;

6. Особенности для разных конфигураций 1С

Хотя платформа 1С:Предприятие предоставляет универсальные инструменты, некоторые конфигурации имеют свои нюансы. Рассмотрим наиболее распространённые:

1С:Бухгалтерия 8.3:

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

ВЫБРАТЬ

РегистрБухгалтерии.ХозОперации.Период КАК Период,

ДнейВМесяце(РегистрБухгалтерии.ХозОперации.Период) КАК ДнейВМесяце

ИЗ

РегистрБухгалтерии.ХозОперации КАК РегистрБухгалтерии.ХозОперации

ГДЕ

РегистрБухгалтерии.ХозОперации.Период МЕЖДУ &Начало И &Конец

1С:Зарплата и Управление Персоналом (ЗУП):

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

КоличествоДней = ?(Месяц = 2 И ВисокосныйГод(Год), 29, ?(Месяц = 2, 28, ДнейВМесяце(Дата(Год, Месяц, 1))));

1С:Управление Торговлей (УТ):

В торговле количество дней в месяце может влиять на аналитику продаж, планирование закупок или расчёт оборотных средств. Например, при формировании отчёта "ABC/XYZ-анализ" иногда нормируют данные на количество дней, чтобы сравнивать месяца с разной длительностью. Здесь удобно использовать динамические списки с вычисляемыми полями.

📊 Какую конфигурацию 1С вы используете чаще всего?
Бухгалтерия 8.3
Зарплата и Управление Персоналом (ЗУП)
Управление Торговлей (УТ)
ERP
Другая

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

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

  • 🗓️ Игнорирование високосных лет: Если вручную проверять февраль на 28 или 29 дней без использования встроенных функций, легко ошибиться. Всегда используйте ДнейВМесяце() или КонецМесяца().
  • 🔢 Неверный тип данных: Передача строки вместо даты (например, "2026-02-01") приведёт к ошибке. Преобразуйте строку в дату с помощью Дата().
  • 📅 Путаница с неполными месяцами: Если вам нужно количество дней в рабочем периоде (например, с 10 по 25 число), не используйте функции для полного месяца. Считайте разницу между датами напрямую.
  • Производительность при массовых расчётах: В циклах по большому количеству дат (например, при обработке архивов) избегайте вызова ДнейВМесяце() для каждой итерации. Лучше заранее сформировать справочник с количеством дней по годам.
⚠️ Внимание: При работе с историческими датами (до 1918 года) помните, что в России тогда использовался юлианский календарь. Функции работают с григорианским календарём, поэтому для точных расчётов может понадобиться корректировка.

Пример ошибочного кода и его исправление:

Ошибка: Попытка получить дни для несуществующей даты:

// ОШИБКА: февраль 2026 года не имеет 30 числа!

КоличествоДней = ДнейВМесяце(Дата(2026, 2, 30));

Исправление: Всегда используйте первую дату месяца:

// ПРАВИЛЬНО

КоличествоДней = ДнейВМесяце(Дата(2026, 2, 1));

8. Практическое применение: примеры из реальных задач

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

Задача 1: Расчёт среднедневной выручки

В отчёте по продажам нужно показать выручку в пересчёте на один день. Формула:

СреднедневнаяВыручка = ОбщаяВыручка / ДнейВМесяце(ПериодОтчёта);

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

Задача 2: Планирование графиков работ

В 1С:ЗУП при формировании графиков сменности нужно учитывать количество рабочих дней. Пример:

РабочиеДни = ПолучитьРабочиеДниВМесяце(Год, Месяц); // Используем функцию из раздела 5

НормаЧасов = РабочиеДни * 8; // При 8-часовом рабочем дне

Задача 3: Автоматическое заполнение документов

При создании документа "Акт выполненных работ" на месяц автоматически подставляем количество дней:

Документ.КоличествоДней = ДнейВМесяце(Документ.ДатаНачала);

Задача 4: Интеграция с внешними системами

При обмене данными с BI-системой (например, Power BI или Tableau) передаём количество дней как дополнительный параметр для корректной визуализации:

ДанныеДляЭкспорта.Добавить("ДнейВМесяце", ДнейВМесяце(Период));
💡

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

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

Можно ли использовать функцию ДнейВМесяце() для дат до 1900 года?

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

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

Используйте справочник "ПроизводственныйКалендарь" в конфигурациях ЗУП или ERP. Пример кода:

РабочиеДни = 0;

Для Каждого День Из Календарь.ПраздничныеДни Цикл

Если День.Дата.Месяц = НужныйМесяц И День.Дата.Год = НужныйГод Тогда

РабочиеДни = РабочиеДни - 1; // Вычитаем праздники из общего количества

КонецЕсли;

КонецЦикла;

Почему функция ДнейВМесяце() возвращает 0 для некоторых дат?

Скорее всего, вы передаёте некорректную дату (например, 31 февраля или 0000-00-00). Всегда проверяйте входные параметры:

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

Возврат 0;

КонецЕсли;

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

Не вызывайте ДнейВМесяце() в цикле. Вместо этого:

  1. Создайте на сервере временную таблицу с предварительно рассчитанными значениями.
  2. Используйте кэширование (например, через Соответствие).
  3. Для типовой ЗУП можноpull данные из регистра сведений "Календари".
Есть ли разница между 1С 8.2 и 1С 8.3 в этих функциях?

Нет, функции ДнейВМесяце() и КонецМесяца() работают одинаково в обеих версиях. Однако в 8.3 добавлена поддержка Null (неопределённое значение), поэтому проверки на ЗначениеЗаполнено() становятся актуальнее.