Расчет количества дней в месяце — казалось бы, простая задача, но в 1С:Предприятие она имеет свои особенности. Разработчикам и аналитикам часто приходится решать эту задачу при формировании отчетов, расчете зарплаты, планировании графиков или работе с календарными данными. Ошибки в таких расчетах могут привести к искажению финансовых показателей, неправильному начислению премий или сбоям в логистических цепочках.
В этой статье мы разберем 5 рабочих способов получить количество дней в любом месяце — от стандартных функций платформы до программного кода с учетом високосных годов. Особое внимание уделим нюансам, которые возникают при работе с датами в разных конфигурациях 1С 8.3 и 1С 7.7, а также типичным ошибкам, которые допускают даже опытные специалисты.
1. Стандартная функция ДнейВМесяце() — самый простой способ
Платформа 1С:Предприятие 8 предоставляет встроенную функцию ДнейВМесяце(), которая возвращает количество дней в указанном месяце с учетом високосных годов. Это наиболее оптимальный вариант для большинства задач, так как не требует написания дополнительного кода и учитывает все календарные особенности.
Синтаксис функции:
ДнейВМесяце(<Дата>)
Где <Дата> — любая дата из интересующего вас месяца. Например, чтобы узнать количество дней в феврале 2026 года, достаточно передать любую дату февраля:
КоличествоДней = ДнейВМесяце('20260201'); // Вернет 29 (високосный год)
- ✅ Преимущества: простота, надежность, учет високосных годов
- ⚠️ Ограничения: работает только в 1С 8.x, в 1С 7.7 аналога нет
- 🔄 Альтернатива: для старых версий придется использовать программный расчет
Если вам нужно получить количество дней в текущем месяце, используйте конструкцию ДнейВМесяце(ТекущаяДата()).
2. Программный расчет с учетом високосных годов
Если по каким-то причинам вы не можете использовать ДнейВМесяце() (например, работаете в 1С 7.7 или нуждаетесь в дополнительной логике), можно написать собственную функцию. Основная сложность здесь — корректный учет високосных годов, которые бывают:
- 🔢 Каждый год, номер которого делится на 4 (2026, 2028, 2032...)
- ❌ Исключение: годы, делящиеся на 100, не являются високосными (1900, 2100)
- ✅ Исключение из исключения: годы, делящиеся на 400, все-таки високосные (2000, 2400)
Вот пример кода для 1С 8.3, который учитывает все эти правила:
Функция КоличествоДнейВМесяце(Год, Месяц)
Если Месяц = 2 Тогда
Если (Год % 4 = 0) И ((Год % 100 <> 0) Или (Год % 400 = 0)) Тогда
Возврат 29; // Високосный год
Иначе
Возврат 28;
КонецЕсли;
ИначеЕсли (Месяц = 4) Или (Месяц = 6) Или (Месяц = 9) Или (Месяц = 11) Тогда
Возврат 30;
Иначе
Возврат 31;
КонецЕсли;
КонецФункции
Вызов функции:
ДниФевраля2026 = КоличествоДнейВМесяце(2026, 2); // Вернет 29
3. Работа с объектами типа Дата: получение последнего дня месяца
Еще один эффективный способ — использовать методы объекта Дата для получения последнего дня месяца, а затем вычислять его номер. Этот подход особенно удобен, когда вам нужно не только количество дней, но и сама дата последнего дня (например, для формирования отчетов "с начала месяца по его конец").
Пример кода:
ДатаНачала = '20260201'; // 1 февраля 2026
ПоследнийДень = КонецМесяца(ДатаНачала); // Вернет '20260229'
КоличествоДней = День(ПоследнийДень); // Вернет 29
Функция КонецМесяца() автоматически учитывает високосные годы и возвращает корректную дату. Этот метод часто используется в бухгалтерских конфигурациях для расчета сроков уплаты налогов или закрытия периодов.
Что будет, если передать в КонецМесяца() несуществующую дату?
Если передать дату типа '20260230' (30 февраля 2026), платформа 1С автоматически скорректирует её на последний валидный день месяца — '20260229'. Это поведение заложено в механизм обработки дат и помогает избежать ошибок при ручном вводе.
4. Использование запросов для массового расчета
Когда требуется получить количество дней в месяце для большого набора дат (например, при анализе временных рядов или формировании сводных отчетов), удобно использовать язык запросов 1С. Это позволяет обработать данные пакетно, не прибегая к циклу в коде.
Пример запроса, который возвращает количество дней в каждом месяце 2026 года:
ВЫБРАТЬ
МЕСЯЦ(&Дата) КАК Месяц,
ДЕНЬ(КОНЕЦМЕСЯЦА(&Дата)) КАК ДнейВМесяце
ИЗ
(ВЫБРАТЬ ДОБАВИТЬМЕСЯЦ(ДАТАВРЕМЯ(2026, 1, 1), МЕСЯЦ - 1) КАК Дата
ИЗ
Числа(1, 12) КАК МЕСЯЦ) КАК Календарь
Результат запроса:
| Месяц | Дней в месяце |
|---|---|
| 1 | 31 |
| 2 | 29 |
| 3 | 31 |
| 4 | 30 |
| 5 | 31 |
Такой подход особенно полезен при работе с регистрами накопления или виртуальными таблицами, где требуется агрегировать данные по календарным периодам.
Убедитесь, что февраль високосного года возвращает 29 дней|
Проверьте апрель, июнь, сентябрь и ноябрь — они должны вернуть 30 дней|
Остальные месяцы должны возвращать 31 день|
Сравните результаты со стандартной функцией ДнейВМесяце() для контрольной даты-->
5. Особенности работы с датами в 1С 7.7
В 1С:Предприятие 7.7 нет встроенной функции ДнейВМесяце(), поэтому расчет приходится реализовывать вручную. Основные сложности связаны с:
- 📅 Отсутствием типа
Датакак объекта — даты представлены строками или числами - 🔄 Необходимостью самостоятельной проверки високосных годов
- ⚠️ Риском ошибок при конвертации форматов дат
Пример кода для 1С 7.7:
Функция ДнейВМесяце77(ДатаСтрока) // Формат "ГГГГММДД" или "ГГГГ-ММ-ДД"
Год = Число(Лев(ДатаСтрока, 4));
Месяц = Число(Сред(ДатаСтрока, 5, 2));
Если Месяц = 2 Тогда
Если (Год % 4 = 0) И ((Год % 100 <> 0) Или (Год % 400 = 0)) Тогда
ДнейВМесяце77 = 29;
Иначе
ДнейВМесяце77 = 28;
КонецЕсли;
ИначеЕсли (Месяц = 4) Или (Месяц = 6) Или (Месяц = 9) Или (Месяц = 11) Тогда
ДнейВМесяце77 = 30;
Иначе
ДнейВМесяце77 = 31;
КонецЕсли;
КонецФункции
⚠️ Внимание: В 1С 7.7 формат даты зависит от региональных настроек. Перед использованием функции убедитесь, что строка даты передается в ожидаемом формате (например,"20260201"вместо"01.02.2026").
6. Типичные ошибки и как их избежать
Даже опытные разработчики иногда допускают ошибки при расчете дней в месяце. Вот наиболее распространенные из них:
- Игнорирование високосных лет. Забывают проверить делимость года на 4, 100 и 400, из-за чего февраль всегда возвращает 28 дней.
- Неправильный формат даты. В 1С 7.7 передают дату в неверном формате (например,
"01.02.2026"вместо"20260201"), что приводит к сбоям. - Путаница с нумерацией месяцев. В некоторых языках программирования месяцы нумеруются с 0, а в 1С — с 1. Это может вызвать ошибку на 1 месяц.
- Использование неактуальных функций. В старых конфигурациях иногда встречаются самописные функции с ошибками, которые копируются из проекта в проект.
Критическая ошибка: если вы рассчитываете рабочие дни (а не календарные), не забывайте исключать выходные и праздники. Для этого в 1С есть отдельный механизм — Календари (объекты конфигурации), которые учитывают производственный календарь РФ.
⚠️ Внимание: При работе с датами в 1С:Зарплата и Управление Персоналом или 1С:ERP используйте встроенные календари для расчета рабочих дней. Самостоятельный расчет может привести к ошибкам в начислении зарплаты или планировании задач.
7. Практическое применение: где нужен расчет дней в месяце
Знание количества дней в месяце требуется во многих бизнес-задачах. Вот несколько реальных примеров:
- 💰 Расчет зарплаты: определение количества отработанных дней для начисления оклада или премий.
- 📊 Финансовая отчетность: распределение доходов/расходов по календарным периодам.
- 📦 Логистика: планирование графиков поставок с учетом последнего дня месяца.
- 📅 CRM-системы: автоматическое продление контрактов или подписок.
- 🏦 Банковские решения: расчет процентов по кредитам или депозитам.
Например, в 1С:Бухгалтерия количество дней в месяце используется для:
- Распределения косвенных расходов пропорционально выручке
- Расчета амортизации основных средств
- Определения сроков уплаты авансовых платежей по налогам
Всегда проверяйте расчет дней в месяце на крайние случаи: февраль високосного года (29 дней), апрель (30 дней) и месяцы с 31 днем. Это поможет избежать ошибок в критичных расчетах.
FAQ: Частые вопросы по расчету дней в месяце в 1С
Можно ли использовать ДнейВМесяце() для исторических дат (например, 1900 год)?
Да, функция корректно работает с любыми датами в диапазоне, поддерживаемом 1С (обычно с 01.01.0001 по 31.12.9999). Для 1900 года она вернет 28 дней в феврале, так как 1900-й не был високосным (делится на 100, но не на 400).
Как получить количество рабочих дней в месяце?
Для этого используйте объект Календарь (в конфигурациях типа 1С:Зарплата). Пример:
Календарь = Календари.ПроизводственныйКалендарь;
РабочиеДни = Календарь.КоличествоРабочихДней(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
Это учтет все официальные праздники и выходные согласно трудовому законодательству РФ.
Почему моя самописная функция для 1С 7.7 ошибается на 1 день?
Наиболее вероятная причина — неверная нумерация месяцев. В 1С 7.7 месяцы, как и в 1С 8, нумеруются с 1 (январь = 1), но иногда разработчики по привычке от других языков начинают с 0. Проверьте условие Если Месяц = 2 — возможно, вам нужно сравнивать с 1 (февраль).
Можно ли получить количество дней в месяце через Формат()?
Нет, функция Формат() предназначена для преобразования данных в строку и не подходит для математических расчетов. Однако вы можете использовать её для отображения результата:
Сообщить(Формат(ДнейВМесяце(ТекущаяДата()), "ЧД=D")); // Выведет "ЧД=31"
Как посчитать дни в месяце для даты в формате UNIX-time?
Сначала преобразуйте UNIX-time в стандартную дату 1С:
ДатаИзUnix = НачалоДня(ДобавитьСекунды('19700101', ВашеUnixВремя));
КоличествоДней = ДнейВМесяце(ДатаИзUnix);