Разработка и Конфигурация · 11 мин
Как получить дату начала месяца в 1С
Как получить дату начала месяца в 1С: функция НачалоМесяца, примеры кода, запросы, типичные ошибки и проверка результата для разработчиков и пользователей.
Задача получить первое число месяца от произвольной даты встречается в 1С постоянно: при формировании отчётов за месяц, расчёте периодов в документах, отборах в запросах и обработках. Встроенный язык платформы содержит готовую функцию для этого — писать собственные вычисления через день, месяц и год не нужно.
Основной инструмент — функция НачалоМесяца(), которая принимает дату и возвращает дату, соответствующую первому числу того же месяца, с временем 00:00:00. Она работает одинаково в тонком клиенте, толстом клиенте и на сервере, не зависит от региональных настроек и корректно обрабатывает переходы через год.
Ниже разобраны синтаксис функции, готовые примеры кода, получение начала месяца в запросах, альтернативные способы и типичные ошибки, которые приводят к неверным периодам в отчётах и документах.
Функция НачалоМесяца: синтаксис и принцип работы
Функция объявлена в глобальном контексте встроенного языка и доступна без подключения общих модулей. Синтаксис предельно простой:
НачалоМесяца(<Дата>)
Единственный параметр — значение типа Дата. Результат — тоже значение типа Дата, у которого день установлен в 1, а время — в начало дня, то есть 00:00:00. Если передать, например, дату '20260315143000' (15 марта, 14:30), функция вернёт '20260301000000' — 1 марта, полночь.
Функция не изменяет исходное значение: даты в 1С передаются по значению, поэтому переменная, которую вы передали в НачалоМесяца, останется прежней. Результат нужно явно присвоить переменной или использовать в выражении.
Если передать пустую дату ('00010101000000'), функция вернёт ту же пустую дату — ошибки не будет, но и осмысленного результата тоже. Поэтому перед вызовом стоит проверять заполненность даты, особенно если она приходит из реквизита документа или параметра обработки.
Примеры кода для типовых сценариев
Самый частый сценарий — получить начало месяца от текущей даты или от даты документа. Примеры ниже можно вставить в модель формы, общий модуль или консоль кода без доработок.
// Начало текущего месяца
НачалоТекущегоМесяца = НачалоМесяца(ТекущаяДатаСеанса());
// Начало месяца от даты документа
НачалоМесяцаДокумента = НачалоМесяца(Объект.Дата);
// Начало месяца от произвольной даты
ПроизвольнаяДата = Дата(2026, 6, 20, 15, 45, 0);
ПервоеЧисло = НачалоМесяца(ПроизвольнаяДата); // 01.06.2026 0:00:00
Обратите внимание на использование ТекущаяДатаСеанса() вместо ТекущаяДата(). В серверном коде и в клиент-серверном режиме правильнее опираться на дату сеанса — она учитывает часовой пояс информационной базы и не зависит от настроек компьютера пользователя.
Часто начало месяца нужно как граница периода отчёта. В паре с ним используется функция КонецМесяца(), которая возвращает последнее число месяца со временем 23:59:59:
ДатаНачала = НачалоМесяца(Отчет.Период);
ДатаОкончания = КонецМесяца(Отчет.Период);
ДатаНачала = НачалоМесяца(ТекущаяДатаСеанса());
ДатаОкончания = КонецМесяца(ТекущаяДатаСеанса());
Сообщить("Период: " + ДатаНачала + " - " + ДатаОкончания);Начало месяца в запросах
В языке запросов функции встроенного языка недоступны — там используется собственная конструкция НАЧАЛОПЕРИОДА. Она принимает два параметра: выражение с датой и периодичность.
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(Продажи.Период, МЕСЯЦ) КАК НачалоМесяца,
СУММА(Продажи.СуммаОборот) КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты КАК Продажи
СГРУППИРОВАТЬ ПО
НАЧАЛОПЕРИОДА(Продажи.Период, МЕСЯЦ)
Такая группировка — стандартный способ свернуть обороты до месяца. Вместо МЕСЯЦ можно указать ДЕНЬ, НЕДЕЛЯ, КВАРТАЛ, ГОД и другие периодичности, но для начала месяца нужен именно параметр МЕСЯЦ.
Если нужно отобрать записи только текущего месяца, вычислите границу в коде и передайте её в запрос параметром — это эффективнее, чем вычислять НАЧАЛОПЕРИОДА для каждой строки в условии ГДЕ:
Запрос.УстановитьПараметр("НачалоМесяца", НачалоМесяца(ТекущаяДатаСеанса()));
Запрос.Текст =
"ВЫБРАТЬ *
|ИЗ Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ Реализация.Дата >= &НачалоМесяца";
Начало месяца произвольного периода: прошлый, следующий, смещение
На практике редко нужен только текущий месяц. Для смещения на заданное количество месяцев применяется функция ДобавитьМесяц(). Порядок вызова важен: сначала смещение, потом приведение к началу месяца — либо наоборот, в зависимости от задачи.
// Начало прошлого месяца
НачалоПрошлогоМесяца = НачалоМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -1));
// Начало следующего месяца
НачалоСледующегоМесяца = НачалоМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), 1));
// Начало месяца, который был полгода назад
НачалоМесяцаСмещение = НачалоМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -6));
Функция ДобавитьМесяц корректно обрабатывает крайние случаи: при добавлении месяца к 31 января результатом будет последний день февраля, а не несуществующая дата. Поэтому комбинация ДобавитьМесяц + НачалоМесяца безопасна для любых исходных дат.
Для вычисления начала месяца по номеру месяца в конкретном году удобен конструктор даты: НачалоМесяца = Дата(Год, НомерМесяца, 1). Это читаемее, чем арифметика с количеством секунд, и не подвержено ошибкам с длиной месяцев.
- 1Определите исходную дату: текущая дата сеанса, дата документа или параметр отчёта
- 2Проверьте, что дата заполнена (не равна '00010101000000')
- 3При необходимости сместите период функцией ДобавитьМесяц
- 4Примените НачалоМесяца к полученной дате
- 5В запросе используйте НАЧАЛОПЕРИОДА(Поле, МЕСЯЦ) или передайте вычисленную границу параметром
- 6Проверьте результат выводом в сообщение или отладчиком
Проверка результата и контрольные точки
Убедиться, что дата начала месяца вычислена правильно, можно несколькими способами. Самый быстрый — вывести значение через Сообщить() или посмотреть в отладчике, поставив точку останова после вычисления.
Признаки корректного результата: день даты равен 1, время — 00:00:00, месяц и год совпадают с месяцем и годом исходной даты (если не было смещения через ДобавитьМесяц). Если время отличается от полуночи — скорее всего, вместо НачалоМесяца была использована исходная дата без обработки.
При использовании результата в отчётах на СКД проверьте, что параметр периода имеет тип Дата с составом «Дата и время», иначе граница может обрезаться. Для периодов отчётов удобнее использовать тип СтандартныйПериод, где начало периода уже задаётся с точностью до секунды.
Как проверить результат
Равен 1
Совпадает с днём исходной даты — функция не применена
00:00:00
Сохранилось исходное время, например 14:30:00
Совпадают с исходной датой (без смещения)
Смещены на месяц — лишний вызов ДобавитьМесяц
Возвращается пустая дата, есть проверка заполненности
Пустая дата попадает в запрос и ломает отбор
Типичные ошибки и ограничения
Первая распространённая ошибка — попытка получить начало месяца вычитанием дней: Дата - (День(Дата) - 1) * 86400. Такой код работает только при строгом контроле типов и времени, плохо читается и ломается при переходе на границу года, если день вычислен неверно. Встроенная функция решает задачу одной строкой.
Вторая ошибка — использование начала месяца как правой границы периода. Условие Дата <= НачалоМесяца(Дата) отберёт только документы ровно в полночь первого числа. Для правой границы нужен КонецМесяца или конструкция «меньше начала следующего месяца».
Третья ошибка — применение НачалоМесяца к строковому представлению даты. Функция принимает только тип Дата; если дата хранится как строка, её сначала нужно преобразовать, иначе будет ошибка выполнения. Аналогично в запросе НАЧАЛОПЕРИОДА не работает со строковыми полями.
Альтернативные способы и когда они оправданы
Помимо НачалоМесяца, начало периода можно получить через функцию НачалоДня() в сочетании с конструктором даты: НачалоДня(Дата(Год(Д), Месяц(Д), 1)). Результат идентичен, но код длиннее — такой вариант оправдан только если внутри выражения уже вычисляются год и месяц для других целей.
В типовых конфигурациях (БСП — библиотека стандартных подсистем) есть общие модули для работы с датами, например функции получения начала периода в календарных расчётах. Если конфигурация построена на БСП, стоит использовать её механизмы для единообразия кода, но для простой задачи встроенной функции достаточно.
В пользовательском режиме без программирования начало месяца можно задать в настройках отчёта через стандартные варианты периода: «Этот месяц», «Прошлый месяц» и подобные. Это удобно для аналитиков и пользователей, которым не нужно писать код.
Сравнение вариантов
Основной способ в модуле. Ограничение: только тип Дата на входе
Для группировки и отборов в запросах. Не работает вне текста запроса
Когда известны номер месяца и год, а не готовая дата
Для пользователя без программирования; не подходит для произвольной логики
Что важно запомнить
Начало месяца в коде получают функцией НачалоМесяца(Дата), в запросах — НАЧАЛОПЕРИОДА(Поле, МЕСЯЦ). Для смещения по месяцам добавляйте ДобавитьМесяц, для правой границы периода — КонецМесяца. Перед вызовом проверяйте, что дата заполнена и имеет тип Дата.
Частые вопросы
Что вернёт НачалоМесяца, если передать пустую дату?
Функция вернёт пустую дату '00010101000000' без ошибки. Поэтому перед вызовом желательно проверять заполненность, иначе пустое значение может попасть в параметр запроса и исказить отбор.
Как получить начало месяца в запросе 1С?
Используйте конструкцию НАЧАЛОПЕРИОДА(ПолеДаты, МЕСЯЦ). Функцию НачалоМесяца из встроенного языка в тексте запроса вызвать нельзя — это разные синтаксисы.
Чем НачалоМесяца отличается от НачалоДня?
НачалоДня возвращает ту же дату с временем 00:00:00, не меняя число. НачалоМесяца дополнительно устанавливает день в 1. Для первого числа месяца результаты обеих функций совпадают.
Как получить начало прошлого месяца?
Скомбинируйте функции: НачалоМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -1)). ДобавитьМесяц корректно обрабатывает переход через год и разную длину месяцев.
Почему в отчёт попадают лишние или не попадают нужные документы при отборе по месяцу?
Чаще всего границы периода заданы неверно: начало месяца использовано как правая граница или время в дате не сброшено. Правильная пара границ — НачалоМесяца и КонецМесяца от одной и той же даты.
Работает ли НачалоМесяца с високосными годами и 31 числом?
Да. Функция просто устанавливает день в 1 и время в полночь, поэтому исходное число месяца и високосность года на результат не влияют.