Как получить количество календарных дней в месяце в 1С 8: подробное руководство

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Метод 1: Использование встроенных функций языка 1С

Самый быстрый и лаконичный способ получить число дней в месяце — это комбинация функций День и КонецМесяца. Давайте проанализируем, как это работает. Функция КонецМесяца возвращает дату и время последнего мгновения указанного месяца (23:59:59). Поскольку дата последнего дня месяца совпадает с порядковым номером этого дня, функция День вернет нам именно общее количество дней.

Рассмотрим конкретный пример кода:


// Определим произвольную дату
НашаДата = Дата(2023, 02, 15); // Февраль 2023 года

// Получаем количество дней
КоличествоДней = День(КонецМесяца(НашаДата));

// Для февраля 2023 года результат будет 28
Сообщить("В текущем месяце " + КоличествоДней + " дн.");

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

Метод 2: Вычисление через разницу дат

Иногда в алгоритмах удобнее использовать математический подход, основанный на разности между началом текущего месяца и началом следующего. Разберем этот алгоритм по шагам. Мы знаем, что при вычитании одной даты из другой в 1С результат возвращается в секундах. Чтобы перевести секунды в дни, их нужно разделить на количество секунд в сутках (86400).

Посмотрим на пример реализации:


НашаДата = ТекущаяДата();
НачалоЭтогоМесяца = НачалоМесяца(НашаДата);
НачалоСледующегоМесяца = ДобавитьМесяц(НачалоЭтогоМесяца, 1);

КоличествоДней = (НачалоСледующегоМесяца - НачалоЭтогоМесяца) / 86400;

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

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

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

Вариант А (наиболее оптимальный):

Используем встроенную функцию запроса ДЕНЬ к результату функции КОНЕЦПЕРИОДА.


ВЫБРАТЬ
    ДЕНЬ(КОНЕЦПЕРИОДА(&Дата, МЕСЯЦ)) КАК КолДнейВМесяце

Вариант Б (через разность дат):

Если вам требуется вычислить разницу более сложным способом, можно использовать функцию РАЗНОСТЬДАТ. Однако здесь есть нюанс: разность между 1-м числом текущего месяца и 1-м числом следующего даст точное количество дней, а разность между началом и концом одного месяца потребует прибавления единицы.


ВЫБРАТЬ
    РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(&Дата, МЕСЯЦ), КОНЕЦПЕРИОДА(&Дата, МЕСЯЦ), ДЕНЬ) + 1 КАК КолДнейВМесяце

Проанализируем важный аспект: обработка NULL. Если в запросе вы используете левое соединение и поле с датой может быть пустым, функция ДЕНЬ вернет NULL. Чтобы избежать падения отчета или ошибки в расчетах, всегда используйте конструкцию ЕСТЬNULL.


ВЫБРАТЬ
    ЕСТЬNULL(ДЕНЬ(КОНЕЦПЕРИОДА(Таблица.ДатаПродажи, МЕСЯЦ)), 0) КАК КоличествоДней
ИЗ
    РегистрНакопления.Продажи КАК Таблица

Метод 4: Использование производственных календарей (для бизнес-логики)

В типовых конфигурациях, таких как 1С:ЗУП или 1С:ERP, простого количества календарных дней часто недостаточно. Бухгалтеру или расчетчику важно знать количество именно рабочих или выходных дней. Для этого в системе предусмотрен РегистрСведений.ДанныеПроизводственногоКалендаря.

Рассмотрим, как получить данные из этого регистра. Выясним причину, почему это лучше ручного расчета: календарь учитывает официальные переносы праздников, утвержденные правительством, что невозможно вычислить простыми математическими функциями.


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	СУММА(1) КАК КоличествоРабочихДней
    |ИЗ
    |	РегистрСведений.ДанныеПроизводственногоКалендаря КАК Календарь
    |ГДЕ
    |	Календарь.Дата МЕЖДУ &НачалоПериода И &КонецПериода
    |	И Календарь.ВидДня В (ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий), 
    |                         ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный))";

Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекущаяДата()));

Метод 5: Функции Библиотеки стандартных подсистем (БСП)

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

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

КалендарныеГрафики.КоличествоДнейВПериоде(ДатаНачала, ДатаОкончания, Календарь)

Дополнительные задачи: Дни в году и високосность

Разберем ситуацию, когда вам нужно определить количество дней в году. Часто программисты пытаются проверять остаток от деления года на 4, но в 1С есть более изящный способ, аналогичный методу разности дат:


// Вычисляем разницу между 1 января текущего и следующего года
КоличествоДнейВГоду = (Дата(Год(НашаДата) + 1, 1, 1) - Дата(Год(НашаДата), 1, 1)) / 86400;

Если результат равен 366 — год високосный. Аналогично можно быстро проверить количество дней в феврале:

ДнейВФеврале = День(КонецМесяца(Дата(Год(НашаДата), 2, 1)));

Подведение итогов

Мы рассмотрели различные подходы к определению количества дней в месяце в среде 1С. Подведем итог:

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

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

← На главную