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

В этой статье мы разберем все актуальные способы получения текущего месяца в 1С 8.3 и 8.2, включая редко документированные приемы для специфических задач. Вы узнаете, как избежать типичных ошибок (например, когда функция возвращает не тот месяц из-за неверного формата даты), как работать с многопользовательскими базами, и почему иногда лучше использовать НачалоМесяца() вместо прямого извлечения номера. Материал будет полезен как начинающим разработчикам, так и опытным программистам, столкнувшимся с неочевидными багами при работе с календарем.

1. Базовый способ: функция ТекущаяДата()

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

ТекущийМесяц = ТекущаяДата().Месяц();

Этот код вернет число от 1 до 12, где 1 — январь, а 12 — декабрь. Важно помнить, что:

  • 📅 Функция зависит от временной зоны сервера 1С (если код выполняется на сервере) или локального компьютера (при клиентском выполнении).
  • ⚡ В многопользовательских базах все клиенты получат одинаковый результат, если код выполняется на сервере.
  • 🔄 Если вам нужно название месяца (например, "Июнь"), потребуется дополнительная обработка (см. раздел 4).

Пример использования в реальном коде:

Если ТекущаяДата().Месяц() = 12 Тогда

Сообщить("Сейчас декабрь — пора готовить годовой отчет!");

КонецЕсли;

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

2. Рабочая дата vs Текущая дата: в чем разница?

Многие разработчики путают ТекущаяДата() и РабочаяДата(). Последняя возвращает дату, установленную в настройках 1С:Предприятия как "рабочую" (например, для тестирования отчетов за прошлые периоды). Это критично для бухгалтерских задач, где требуется эмуляция исторических данных.

Чтобы получить месяц из рабочей даты:

МесяцРабочейДаты = РабочаяДата().Месяц();

Ключевые отличия:

Функция Источник данных Применение Зависит от пользователя?
ТекущаяДата() Системное время Реальные операции (например, создание документа "сейчас") Да (если клиентский контекст)
РабочаяДата() Настройки 1С Тестирование, отчеты за прошлые периоды Нет
НачалоМесяца() Любая переданная дата Периодические расчеты (зарплата, налоги) Зависит от входного параметра

Пример, когда важно использовать РабочаяДата():

// Проверяем, что отчет формируется за текущий рабочий месяц

Если РабочаяДата().Месяц() <> ТекущаяДата().Месяц() Тогда

Предупреждение("Внимание! Рабочая дата не совпадает с текущей!");

КонецЕсли;

📊 Какой способ получения месяца вы используете чаще?
ТекущаяДата()
РабочаяДата()
НачалоМесяца()
Свой вариант

3. Получение месяца для произвольной даты

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

ДатаДокумента = Документы.ЗаказПокупателя.Даты.Дата;

МесяцДокумента = ДатаДокумента.Месяц();

Типичные сценарии:

  • 📊 Фильтрация отчетов по месяцу создания документа.
  • 💰 Расчет зарплаты за конкретный месяц.
  • 📦 Анализ складских остатков по периодам.

Важный нюанс: если дата хранится в строковом формате (например, в файле обмена), сначала преобразуйте её в тип Дата:

СтрокаДаты = "2026-06-15";

ДатаИзСтроки = Дата(СтрокаДаты);

Месяц = ДатаИзСтроки.Месяц();

⚠️ Внимание: При парсинге строковых дат учитывайте региональные настройки 1С. Формат "ГГГГ-ММ-ДД" универсален, но "ДД.ММ.ГГГГ" может интерпретироваться некорректно в некоторых конфигурациях.

Используется ли тип Данные.Дата (не строка)?|Учтена ли временная зона при серверных вызовах?|Проверены ли граничные случаи (1 января, 31 декабря)?|Документированы ли различия между ТекущейДатой и РабочейДатой?-->

4. Как получить название месяца (не номер)

Часто требуется вывести не номер месяца (1–12), а его название на русском языке (например, "Июнь"). Для этого в 1С есть функция Формат() с параметром форматирования "ММММ":

НазваниеМесяца = Формат(ТекущаяДата(), "ММММ"); // Вернет "июнь"

НазваниеМесяцаСЗаглавной = СтрЗаменить(Формат(ТекущаяДата(), "ММММ"), "и", "И"); // "Июнь"

Другие варианты форматирования:

  • 🔢 "ММ" — номер месяца с ведущим нулем (01–12).
  • 🔤 "МММ" — краткое название (янв, фев, мар).
  • 📅 "ММММ" — полное название (январь, февраль).

Пример использования в отчете:

ЗаголовокОтчета = "Отчет по продажам за " + Формат(ТекущаяДата(), "ММММ yyyy");

Сообщить(ЗаголовокОтчета); // "Отчет по продажам за июнь 2026"

Как локализовать названия месяцев для других языков?

Для многоязычных баз используйте функцию НСтр() с указанием языка:

НазваниеНаАнглийском = НСтр("ru = 'ММММ'; en = 'MMMM'", ТекущаяДата());

Это вернет название месяца на языке интерфейса текущего пользователя.

5. Работа с началом и концом месяца

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

НачалоТекущегоМесяца = НачалоМесяца(ТекущаяДата()); // 01.06.2026 00:00:00

КонецТекущегоМесяца = КонецМесяца(ТекущаяДата()); // 30.06.2026 23:59:59

Практическое применение:

  • 📈 Фильтрация данных в запросах по диапазону дат.
  • 💼 Автоматическое создание документов на начало/конец месяца (например, начисление аванса).
  • 📊 Сравнение периодов (текущий месяц vs предыдущий).

Пример запроса с использованием НачалоМесяца():

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Сумма(Документ.Сумма) КАК Итого

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Документ

|ГДЕ

| Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода";

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

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

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

Это актуально для расчета дневной зарплаты или амортизации.-->

6. Типовые ошибки и как их избежать

Даже опытные разработчики иногда сталкиваются с неочевидными багами при работе с месяцами в 1С. Вот самые распространенные ловушки:

  1. Путаница с временными зонами: Если сервер и клиент находятся в разных часовых поясах, ТекущаяДата() может вернуть разные результаты. Решение — всегда использовать серверный контекст для критичных операций.
  2. Неучет рабочей даты: Забывают, что РабочаяДата() может отличаться от текущей, из-за чего отчеты формируются не за тот период.
  3. Ошибки при парсинге строк: Попытка извлечь месяц из строки без преобразования в тип Дата приводит к ошибкам или некорректным результатам.
  4. Граничные даты: Код ломается на 1 января или 31 декабря из-за неверной обработки перехода между годами.

Пример кода с потенциальной ошибкой:

// ОШИБКА: если ДатаВСтроке = "31.12.2023", то Месяц будет 12, но год — 2023

СтрокаДаты = "31.12.2023";

Месяц = Сред(СтрокаДаты, 4, 2); // "12" — но это строка, а не число!

Правильный вариант:

ДатаИзСтроки = Дата(СтрокаДаты);

Месяц = ДатаИзСтроки.Месяц(); // 12 (число)

💡

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

7. Продвинутые приемы: месяц в запросах и динамические периоды

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

Запрос.Текст =

"ВЫБРАТЬ

| МЕСЯЦ(Документ.Дата) КАК НомерМесяца,

| СУММА(Документ.Сумма) КАК Итого

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Документ

|СГРУППИРОВАТЬ ПО

| МЕСЯЦ(Документ.Дата)";

Другие полезные функции в запросах:

  • 📅 НАЧАЛОПЕРИОДА(, "МЕСЯЦ") — начало месяца для каждой записи.
  • 🔙 ГОД() — извлечение года (полезно для группировки по годам и месяцам).
  • 📊 ДЕНЬ() — день месяца (например, для анализа пиковых продаж).

Пример динамического формирования периода "с начала месяца по сегодня":

НачалоПериода = НачалоМесяца(ТекущаяДата());

КонецПериода = ТекущаяДата();

Запрос.Текст =

"ВЫБРАТЬ

| Документ.Номер КАК НомерДокумента

|ИЗ

| Документ.ПоступлениеТоваров КАК Документ

|ГДЕ

| Документ.Дата МЕЖДУ &Начало И &Конец";

Запрос.УстановитьПараметр("Начало", НачалоПериода);

Запрос.УстановитьПараметр("Конец", КонецПериода);

Часто задаваемые вопросы

Как получить месяц на английском языке?

Используйте функцию НСтр() с указанием языка:

МесяцНаАнглийском = НСтр("ru = 'ММММ'; en = 'MMMM'", ТекущаяДата());

Это вернет название месяца на языке интерфейса текущего пользователя. Для принудительного выбора языка укажите его явно, например: НСтр("en = 'MMMM'", ТекущаяДата()).

Почему ТекущаяДата().Месяц() возвращает неверный месяц?

Наиболее вероятные причины:

  1. Код выполняется на клиенте, а системное время пользователя отличается от серверного.
  2. В базе установлена рабочая дата, отличная от текущей (проверьте РабочаяДата()).
  3. Переменная, из которой извлекается месяц, не является типом Дата (например, строка в неверном формате).

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

Как получить месяц в формате "01" (с ведущим нулем)?

Используйте функцию Формат() с параметром "ММ":

МесяцСНулем = Формат(ТекущаяДата(), "ММ"); // "06" для июня

Альтернативно можно использовать СтрДлина():

Месяц = ТекущаяДата().Месяц();

МесяцСНулем = ?(СтрДлина(Месяц) = 1, "0" + Месяц, Месяц);

Можно ли получить месяц для даты в будущем?

Да, никаких ограничений нет. Просто передайте нужную дату в функцию:

БудущаяДата = Дата(2026, 12, 31);

Месяц = БудущаяДата.Месяц(); // 12

Это полезно для планирования или тестирования сценариев на будущие периоды.

Как сравнить месяцы двух разных дат?

Сравнивайте числовые значения, извлеченные через .Месяц():

Дата1 = Дата(2026, 6, 15);

Дата2 = Дата(2026, 7, 10);

Если Дата1.Месяц() < Дата2.Месяц() Тогда

Сообщить("Июнь раньше июля");

КонецЕсли;

Для сравнения с учетом года используйте полную дату или функцию НачалоМесяца().