Разработка и Конфигурация · 11 мин
Как получить дату начала года в 1С
Как получить дату начала года в 1С: функция НачалоГода, примеры кода, работа с произвольной датой, запросы, типичные ошибки и способы проверки результата.
Дата начала года — одно из самых частых значений в коде 1С: она нужна при формировании отчётов за период с начала года, расчёте нарастающих итогов, установке диапазонов дат по умолчанию и отборе документов. Во встроенном языке платформы для этого есть готовая функция НачалоГода(), которая принимает дату и возвращает её первый день со временем 00:00:00.
Функция работает одинаково в толстом, тонком и веб-клиенте, доступна и на сервере, и на клиенте, поэтому подходит почти для любого сценария — от обработчика формы до фонового расчёта. Важно только понимать, какое именно значение она возвращает и как подставить её в запрос или параметр отчёта.
Ниже разобраны синтаксис функции, варианты получения начала текущего и произвольного года, использование в запросах и СКД, а также типичные ошибки, из-за которых в отбор попадает не тот период.
Функция НачалоГода: синтаксис и результат
Функция имеет единственный обязательный параметр — значение типа Дата. Синтаксис: НачалоГода(<Дата>). Возвращаемое значение — дата первого дня того года, к которому относится переданная дата, с обнулённым временем.
ДатаНачала = НачалоГода(ТекущаяДатаСеанса());
// Например: 01.01.2026 0:00:00
ДатаНачалаПрошлого = НачалоГода(ДобавитьМесяц(ТекущаяДатаСеанса(), -15));
// начало года для даты, сдвинутой на 15 месяцев назад
Ключевые свойства функции, которые нужно учитывать:
- время результата всегда
00:00:00— это начало календарного дня 1 января; - функция не изменяет переданную дату, а возвращает новое значение;
- если передана пустая дата (
'00010101'), результатом также будет начало года этой пустой даты — проверяйте заполненность входного значения заранее; - функция относится к группе функций работы с датой и доступна без подключения общих модулей.
Как получить начало текущего года
Самый частый сценарий — отчёт или обработка, которые по умолчанию работают «с начала года по текущую дату». Для этого достаточно вычислить начало года от текущей даты сеанса.
// На сервере и на клиенте
НачалоПериода = НачалоГода(ТекущаяДатаСеанса());
КонецПериода = КонецДня(ТекущаяДатаСеанса());
Обратите внимание на выбор функции текущей даты. ТекущаяДатаСеанса() учитывает часовой пояс сеанса и корректно работает в клиент-серверном варианте. Устаревшая ТекущаяДата() на клиенте возвращает дату компьютера пользователя, что при разных часовых поясах может дать «вчерашний» или «завтрашний» год на границе суток.
Если значение нужно показать пользователю на форме, создайте реквизит формы типа Дата и заполните его в обработчике ПриСозданииНаСервере. Так дата подставится один раз при открытии и не будет пересчитываться при каждом обращении к форме.
- 1Добавьте на форму два реквизита типа Дата: НачалоПериода и КонецПериода
- 2В обработчике ПриСозданииНаСервере присвойте НачалоПериода = НачалоГода(ТекущаяДатаСеанса())
- 3Присвойте КонецПериода = КонецДня(ТекущаяДатаСеанса())
- 4Откройте форму и убедитесь, что в поле начала стоит 1 января текущего года
Начало года от произвольной даты
На практике дата часто приходит извне: из документа, параметра обработки или пользовательского ввода. В этом случае просто передайте её в функцию, но предварительно проверьте заполненность.
Функция НачалоГодаДокумента(ДатаДокумента) Экспорт
Если Не ЗначениеЗаполнено(ДатаДокумента) Тогда
Возврат Дата(1, 1, 1); // пустая дата
КонецЕсли;
Возврат НачалоГода(ДатаДокумента);
КонецФункции
Если нужно получить начало года по номеру года без готовой даты, сначала соберите дату конструктором Дата(Год, Месяц, День). Например, Дата(Год(ТекущаяДатаСеанса()), 1, 1) даст тот же результат, что и НачалоГода(), но такой способ удобен, когда известен только номер года.
Для начала предыдущего или следующего года комбинируйте функции: НачалоГода(ДобавитьМесяц(ТекущаяДатаСеанса(), -12)) вернёт 1 января прошлого года. Проверяйте такие выражения на граничных значениях — в январе и декабре, чтобы убедиться, что сдвиг не «перескочил» лишний год.
Начало года в запросе: НАЧАЛОПЕРИОДА
В языке запросов функция называется иначе: НАЧАЛОПЕРИОДА(Дата, ГОД). Она применяется к полям выборки, параметрам и условиям отбора.
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(Продажи.Период, ГОД) КАК НачалоГода,
СУММА(Продажи.СуммаОборот) КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты(
НАЧАЛОПЕРИОДА(&ТекущаяДата, ГОД), , , ) КАК Продажи
СГРУППИРОВАТЬ ПО
НАЧАЛОПЕРИОДА(Продажи.Период, ГОД)
Чаще всего начало года передаётся в виртуальную таблицу оборотов или остатков как параметр периода. Это эффективнее, чем отбирать все записи и фильтровать их в условии ГДЕ: виртуальная таблица сразу рассчитывается на нужном диапазоне, и запрос работает быстрее на больших объёмах данных.
Если параметр &ТекущаяДата вычисляется в коде, надёжнее заранее передать в запрос уже готовое значение НачалоГода(ТекущаяДатаСеанса()) — так запрос становится проще, а результат предсказуемее при отладке в консоли запросов.
Использование в СКД и отчётах
В системе компоновки данных начало года обычно задаётся через параметры НачалоПериода и КонецПериода. Чтобы при открытии отчёта подставлялся период «с начала года», задайте выражение для параметра на вкладке «Параметры» схемы компоновки: &НачалоПериода с типом Дата и значением по умолчанию, вычисляемым в модуле отчёта или через стандартные периоды.
Удобная альтернатива — стандартные периоды. Тип СтандартныйПериод позволяет пользователю выбрать вариант «С начала этого года» без программирования, а в коде получить границы через свойства ДатаНачала и ДатаОкончания.
СтандартныйПериод = Новый СтандартныйПериод(ВариантСтандартногоПериода.СНачалаЭтогоГода);
НачалоГода = СтандартныйПериод.ДатаНачала;
Такой подход предпочтителен в пользовательских отчётах: он даёт знакомый интерфейс выбора периода и исключает ручные ошибки при вводе дат.
Способы получить начало года
Универсальный способ в коде; требует готовой даты и проверки её заполненности
Для текста запроса и виртуальных таблиц; не работает вне запроса
Когда известен только номер года; нужно отдельно получать сам номер года
Для отчётов и настроек пользователя; избыточен для простых вычислений в коде
Проверка результата и граничные случаи
Проверить функцию проще всего в консоли кода или через Сообщить() в отладочной обработке. Убедитесь, что результат имеет ожидаемый вид, включая нулевое время.
ДатаНачала = НачалоГода(ТекущаяДатаСеанса());
Сообщить(Формат(ДатаНачала, "ДЛФ=DT")); // например: 01.01.2026 0:00:00
Обратите внимание на граничные ситуации. Для даты 31 декабря любого года функция вернёт 1 января того же года, а для 1 января — саму эту дату без изменений. Если ваша логика опирается на «начало года относительно другой даты», убедитесь, что не перепутаны функции НачалоГода и ДобавитьМесяц: сдвиг на минус 12 месяцев от 15 марта даст 15 марта прошлого года, а не 1 января.
В клиент-серверном варианте проверяйте вычисления на стороне сервера: если дата вычисляется на клиенте в другом часовом поясе, а сравнивается с серверными данными, на границе года возможны расхождения в один день.
Как проверить результат
1 января текущего года, время 00:00:00
Другой день месяца или ненулевое время
Возвращается та же дата 1 января
Дата сдвигается на прошлый год
В выборку попадают документы с 1 января включительно
Пропадают документы первого дня года или попадает прошлый год
Обработана проверкой ЗначениеЗаполнено
Пустая дата молча уходит в расчёт
Типичные ошибки и ограничения
Наиболее распространённая ошибка — использование начала года как правой границы периода. Выражение КонецПериода = НачалоГода(ТекущаяДатаСеанса()) для отчёта «по начало года» отсекает весь первый день января, потому что время равно 00:00:00. Для правой границы применяйте КонецГода() или КонецДня().
Вторая частая проблема — сравнение дат без учёта времени. Если документ проведён 1 января в 10:30, условие ДатаДокумента = НачалоГода(ДатаДокумента) не выполнится: даты различаются по времени. В отборах используйте неравенства >= и <= либо приводите обе стороны к началу дня.
Ещё одно ограничение: функция работает только со значением типа Дата. Передача строки вида "01.03.2026" вызовет ошибку преобразования типов — строку нужно сначала превратить в дату, например через Дата() с разбором частей или стандартные механизмы ввода.
Что важно запомнить
Начало года в коде получают функцией НачалоГода(Дата), в запросах — НАЧАЛОПЕРИОДА(Дата, ГОД). Результат всегда содержит время 00:00:00, поэтому для конца периода берите КонецГода или КонецДня. Проверяйте заполненность входной даты и используйте ТекущаяДатаСеанса() в клиент-серверном режиме.
Частые вопросы
Чем НачалоГода отличается от НачалоДня?
НачалоГода возвращает 1 января года переданной даты, а НачалоДня — начало того же дня. Обе функции обнуляют время, но сдвигают дату на разные границы календаря. Для периода «с начала года» нужна именно НачалоГода.
Как получить начало года в запросе, если дата хранится в параметре?
Используйте прямо в тексте запроса НАЧАЛОПЕРИОДА(&Дата, ГОД) — параметр подставится в функцию. Альтернатива: вычислить НачалоГода() в коде и передать в запрос уже готовое значение, что упрощает отладку.
Почему документы 1 января не попадают в отбор?
Почти всегда причина во времени: НачалоГода возвращает 00:00:00, а документ проведён позже. Сравнение на равенство не срабатывает. Используйте условие «больше или равно» для начала периода и КонецДня или КонецГода для его конца.
Как получить начало прошлого года?
Сдвиньте дату на 12 месяцев назад и примените функцию: НачалоГода(ДобавитьМесяц(ТекущаяДатаСеанса(), -12)). Проверьте результат в январе — при корректном выражении сдвиг не затрагивает лишний год.
Работает ли НачалоГода на клиенте и на сервере?
Да, функция доступна в обоих контекстах, а также в тонком и веб-клиенте. Различаться может только источник текущей даты: на клиенте ТекущаяДата() берёт время компьютера пользователя, поэтому для серверной логики надёжнее ТекущаяДатаСеанса().
Можно ли получить начало года без функции, через конструктор даты?
Да: Дата(Год(НужнаяДата), 1, 1) даст тот же результат. Такой способ удобен, когда известен только номер года, но в обычном коде НачалоГода читается проще и меньше риск ошибиться в порядке аргументов конструктора.