Как в запросе 1С получить день, месяц и год из даты?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Базовый способ извлечения дня, месяца и года

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

Для этого мы используем следующие конструкции:

  1. ГОД(Дата) — возвращает четырехзначное число (например, 2023).
  2. МЕСЯЦ(Дата) — возвращает порядковый номер месяца (от 1 до 12).
  3. ДЕНЬ(Дата) — возвращает число месяца (от 1 до 31).

Разберем конкретный пример кода запроса:


ВЫБРАТЬ
    Продажи.Ссылка КАК Документ,
    ГОД(Продажи.Дата) КАК ГодПродажи,
    МЕСЯЦ(Продажи.Дата) КАК МесяцПродажи,
    ДЕНЬ(Продажи.Дата) КАК ДеньПродажи
ИЗ
    Документ.РеализацияТоваровУслуг КАК Продажи

В данном примере мы берем дату из документа и «разбиваем» её на три отдельных колонки. Важно понимать, что результатом выполнения этих функций будет тип Число, а не строка или дата.

Мифы о производительности и оптимизация

В процессе обсуждения часто возникает вопрос: не перегружаем ли мы запрос, если вызываем функции ДЕНЬ, МЕСЯЦ и ГОД для одного и того же поля? Рассмотрим это с точки зрения работы СУБД (SQL Server, PostgreSQL).

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

Важный нюанс: если вы работаете с пустой датой (0001-01-01), функции ДЕНЬ и МЕСЯЦ вернут значение 1, а ГОД — значение 1. Это следует учитывать при проверке заполненности реквизитов внутри запроса с помощью ВЫБОР КОГДА.

Расширенные возможности работы с периодами

Зачастую простого получения числа недостаточно. Рассмотрим ситуации, когда нам требуются другие составляющие даты или их комбинации. Выясним, какие еще функции нам доступны:

Если ваша задача связана с анализом времени, мы можем использовать аналогичные функции для часов, минут и секунд:


ВЫБРАТЬ
    ЧАС(Событие.Дата) КАК ЧасСобытия,
    МИНУТА(Событие.Дата) КАК МинутаСобытия,
    СЕКУНДА(Событие.Дата) КАК СекундаСобытия
ИЗ
    РегистрСведений.ЛогСобытий КАК Событие

Использование функции НАЧАЛОПЕРИОДА для группировки

Проанализируем ситуацию: вам нужно сгруппировать продажи по месяцам. Можно ли это сделать через функции ГОД и МЕСЯЦ? Да, но это неудобно, так как вы получите два отдельных числа. Намного эффективнее использовать функцию НАЧАЛОПЕРИОДА.

Эта функция «округляет» дату до начала указанного интервала, сохраняя при этом тип Дата. Посмотрим на пример:


ВЫБРАТЬ
    НАЧАЛОПЕРИОДА(Продажи.Дата, МЕСЯЦ) КАК МесяцОтчета,
    СУММА(Продажи.СуммаДокумента) КАК ИтогоСумма
ИЗ
    Документ.РеализацияТоваровУслуг КАК Продажи
ГРУППИРОВАТЬ ПО
    НАЧАЛОПЕРИОДА(Продажи.Дата, МЕСЯЦ)

В результате мы получим дату вида «01.05.2023 00:00:00» для любой продажи, совершенной в мае. Это стандарт де-факто для построения динамики показателей в 1С. В качестве параметра периода можно использовать: ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД, ДЕКАДА.

Вычисления с датами в запросе

Иногда требуется не просто «разбить» дату, но и изменить её. Разберем две ключевые функции для арифметики дат:

  1. ДОБАВИТЬКДАТЕ: позволяет прибавить к дате определенное количество периодов. Например, чтобы получить дату ровно год назад, мы используем отрицательное значение: ДОБАВИТЬКДАТЕ(ТекущаяДата, ГОД, -1).
  2. РАЗНОСТЬДАТ: вычисляет разницу между двумя датами в определенных единицах. Важно помнить: функция возвращает целое число полных периодов, отбрасывая остаток.

Рассмотрим пример расчета возраста сотрудника в годах:


ВЫБРАТЬ
    Сотрудники.Наименование,
    РАЗНОСТЬДАТ(Сотрудники.ДатаРождения, &ТекущаяДата, ГОД) КАК Возраст
ИЗ
    Справочник.Сотрудники КАК Сотрудники

Подведение итогов

Мы выяснили, что функции ДЕНЬ, МЕСЯЦ и ГОД являются наиболее простым и правильным способом получения компонентов даты в запросе. Они работают быстро, надежно и понятны любому разработчику. Однако для более сложных задач, таких как группировка или расчет интервалов, всегда стоит помнить о существовании НАЧАЛОПЕРИОДА и РАЗНОСТЬДАТ. Правильное комбинирование этих инструментов позволяет решать практически любые задачи по аналитике времени непосредственно на уровне запроса, не прибегая к сложной постобработке в коде на встроенном языке.

← На главную