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

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

Встроенные функции платформы для работы с датами

Платформа 1С:Предприятие предоставляет богатый набор встроенных процедур и функций для манипуляций с календарем. Если вы пишете код на встроенном языке (например, в модуле объекта или обработки), самым простым способом узнать номер месяца является функция Месяц(). Эта функция принимает значение типа Дата и возвращает целое число от 1 до 12.

Рассмотрим простой пример использования. Допустим, у нас есть переменная ТекущаяДата, и нам нужно определить, в каком месяце находится этот момент времени. Код будет выглядеть максимально лаконично.

Месяц() — это не единственная функция в своем роде. Для получения других частей даты существуют аналоги: Год(), День(), Час() и так далее. Использование этих функций предпочтительнее ручного вычисления разницы дат, так как они учитывают все нюансы календаря, включая високосные годы и переходы на летнее время (если это актуально для региона).

💡

Используйте функцию Месяц() вместо преобразования даты в строку и последующего разбора строки — это работает в десятки раз быстрее.

Помимо извлечения номера, часто требуется получить дату начала месяца. Для этого идеально подходит функция МесяцНач(). Она возвращает новую дату, где день установлен в 1, а время обнулено. Это ключевой момент для группировки данных в отчетах, так как позволяет привести разные даты одного месяца к единому знаменателю.

Извлечение месяца в языке запросов 1С

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

Для получения номера месяца в тексте запроса используется функция Месяц(), которая вызывается прямо в списке полей или в условии отбора. Это позволяет базе данных самостоятельно отфильтровать или сгруппировать записи, не передавая лишние данные в приложение 1С. Такой подход существенно снижает нагрузку на сервер при работе с большими объемами документов.

  • 📅 Функция Месяц(Дата) возвращает целое число от 1 до 12.
  • 📅 Функция Год(Дата) возвращает четырехзначное число года.
  • 📅 Функция Квартал(Дата) возвращает номер квартала от 1 до 4.

Часто разработчики забывают, что в условиях отбора (ГДЕ) можно использовать эти функции напрямую. Однако стоит быть осторожным: использование функций от поля в условии ГДЕ может препятствовать использованию индексов в некоторых СУБД, хотя оптимизатор запросов 1С обычно справляется с этим неплохо. Для максимальной производительности при выборке диапазонов лучше использовать сравнение с датами начала и конца периода.

📊 Какой способ выборки по месяцу вы используете чаще?
Функция Месяц() в условии ГДЕ
Сравнение с МесяцНач и КонецМесяца
Выборка всего и фильтрация в коде
Использование регистров срезов

Если вам необходимо сгруппировать документы по месяцам в отчете, вы можете добавить вычисляемое поле в запрос. Например, Месяц(Период) КАК НомерМесяца. Это позволит группировать результаты непосредственно в запросе, используя конструкцию СГРУППИРОВАТЬ ПО. Такой метод является стандартом де-факто для построения аналитических отчетов.

Арифметика дат и вычисление границ периода

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

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

⚠️ Внимание: При сравнении дат помните, что время также участвует в сравнении. Дата "01.02.2026 00:00:00" строго меньше, чем "01.02.2026 12:00:00". Если вы проверяете попадание в интервал, используйте <= для правой границы или функцию КонецМесяца().

Рассмотрим пример расчета количества дней в месяце. Зная дату начала и дату конца, мы можем вычесть одну из другой. Поскольку в 1С разность дат возвращает количество секунд, результат нужно разделить на количество секунд в сутках (86400). Однако проще использовать функцию РазностьДат() с указанием интервала "День".

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

☑️ Проверка корректности периода

Выполнено: 0 / 4

Форматирование и вывод названия месяца

Пользователи редко хотят видеть в отчетах сухие цифры от 1 до 12. Гораздо информативнее отображать название месяца, возможно, в определенном падеже. Для преобразования числового значения месяца в строковое представление используется функция Формат().

Функция Формат() в 1С обладает мощным синтаксисом описания форматов. Чтобы получить полное название месяца, можно использовать строку формата "ДФ=MMMM". Если требуется сокращенное название (янв, фев), используется "ДФ=MMM". Это работает как для встроенного языка, так и в макетах компоновки данных (СКД).

ТекстМесяца = Формат(ТекущаяДата(), "ДФ=MMMM");

// Результат: "Октябрь" (зависит от текущей даты)

Важным аспектом является локаль. 1С автоматически подставляет названия месяцев на языке интерфейса пользователя. Если пользователь работает в английской версии интерфейса, он получит "October". Это избавляет разработчика от необходимости создавать собственные словари переводов.

Нюансы склонения месяцев

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

При использовании СКД (Система Компоновки Данных) вы можете настроить форматирование прямо в настройках отчета, не прописывая код. В конструкторе настроек выберите поле с датой, зайдите в формат и укажите нужный шаблон. Это делает отчеты более гибкими и позволяет пользователю самому менять вид представления даты.

Сравнение методов и производительность

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

Ниже приведена таблица, сравнивающая основные подходы к работе с месяцами в различных сценариях использования.

Метод Где использовать Производительность Сложность
Функция Месяц() Встроенный язык, условия запроса Высокая Низкая
МесяцНач() Группировка, индексы Очень высокая Низкая
Преобразование в строку Вывод на экран, печать Средняя Средняя
Арифметика дат Расчет длительности Высокая Высокая

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

⚠️ Внимание: Избегайте использования преобразования даты в строку (Строка(Дата)) внутри условий отбора запроса. Это приводит к полному сканированию таблицы и игнорированию индексов, что критически замедляет работу системы.

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

Типичные ошибки и способы их избежания

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

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

  • 🛑 Ошибка: сравнение даты с временем и даты без времени.
  • 🛑 Ошибка: использование Месяц(Сегодня()) в цикле вместо вычисления один раз перед циклом.
  • 🛑 Ошибка: попытка вычесть из даты число 1 для получения вчерашнего дня (вычтется 1 секунда, а не 1 день).

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

💡

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

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

Практические примеры кода для разработчиков

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

Пример 1: Проверка, является ли текущий месяц последним в квартале.

Функция ЭтоКонецКвартала(ДатаПроверки)

НомерМесяца = Месяц(ДатаПроверки);

Возврат (НомерМесяца = 3 ИЛИ НомерМесяца = 6 ИЛИ НомерМесяца = 9 ИЛИ НомерМесяца = 12);

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

Пример 2: Получение списка всех месяцев года с их названиями для заполнения выпадающего списка в форме.

Процедура ЗаполнитьСписокМесяцев(СписокМесяцев)

Для Сч = 1 По 12 Цикл

ДатаМесяца = Дата(2026, Сч, 1); // Год не важен, важен номер месяца

Название = Формат(ДатаМесяца, "ДФ=MMMM");

СписокМесяцев.Добавить(Сч, Название);

КонецЦикла;

КонецПроцедуры

⚠️ Внимание: Интерфейс и поведение некоторых функций могут незначительно отличаться в зависимости от версии платформы 1С (8.2, 8.3, 8.4 и выше). Всегда сверяйтесь с синтаксис-помощником вашей конкретной версии платформы, если сталкиваетесь с нестандартным поведением.

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

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

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

Можно ли использовать функцию Месяц() в условиях индексирования?

Сама по себе функция Месяц() не использует индекс по полю даты напрямую для поиска диапазона. Однако оптимизатор запросов 1С достаточно умен, чтобы в некоторых случаях преобразовать условие. Для гарантированного использования индекса лучше явно указывать диапазон: ГДЕ Дата >= НачМесяца И Дата <= КонМесяца.

В чем разница между Месяц() и НомерПериода()

Функция Месяц() возвращает номер месяца в году (1-12). Функция НомерПериода() (если речь идет о регистрах накопления или специфических объектах) может возвращать номер периода в рамках конкретного регистра, что не всегда совпадает с календарным месяцем, если периодичность регистра настроена иначе.

Как обработать ошибку, если передана пустая дата?

Функция Месяц() требует корректного значения даты. Если существует вероятность передачи Неопределено или пустой даты, обязательно добавьте проверку перед вызовом: Если ЗначениеЗаполнено(МояДата) Тогда.. КонецЕсли;. В противном случае система выдаст ошибку скрипта.

Влияет ли смена языка интерфейса на номер месяца?

Нет, функция Месяц() всегда возвращает числовое значение (целое), которое не зависит от языка интерфейса. Зависимость от локали возникает только при форматировании даты в строку для отображения пользователю с помощью функции Формат().