Разработка и Конфигурация · 12 мин
Как определить день недели по дате в 1С
Как определить день недели по дате в 1С: функция ДеньНедели, вывод названия дня, проверка выходных, работа в запросах и типовые ошибки с примерами кода.
Во встроенном языке 1С определить день недели по любой дате можно штатной функцией ДеньНедели() — она принимает значение типа «Дата» и возвращает число от 1 до 7, где 1 соответствует понедельнику, а 7 — воскресенью. Этого достаточно для большинства задач: проверки выходных, расчёта сроков, формирования заголовков отчётов и условий в бизнес-логике.
Задача возникает регулярно: нужно запретить проведение документа в субботу, показать пользователю «понедельник, 12 мая» вместо сухой даты, сдвинуть платёж на ближайший рабочий день или сгруппировать продажи по дням недели в отчёте. Все эти сценарии решаются одной функцией плюс небольшой обвязкой кода.
Важно понимать ограничение: ДеньНедели() знает только календарь и ничего не знает о производственном календаре предприятия. Переносы праздников, сокращённые дни и региональные нерабочие дни она не учитывает — для этого в типовых конфигурациях используется регистр сведений с календарными графиками.
Функция ДеньНедели: синтаксис и значения
Синтаксис предельно прост: ДеньНедели(Дата), где параметр — значение типа «Дата». Результат — число от 1 до 7. Нумерация начинается с понедельника, что соответствует стандарту ISO 8601 и российской привычке считать понедельник первым днём недели.
ДатаПроверки = Дата(2026, 5, 15);
НомерДня = ДеньНедели(ДатаПроверки); // вернёт 3 — среда
Функция работает и на сервере, и на клиенте, в толстом, тонком и веб-клиенте, а также доступна в языке выражений компоновки данных. Она не обращается к базе данных, поэтому вызов практически бесплатен по производительности — её смело можно использовать в циклах и при построчной обработке табличных частей.
Если передать пустую дату (Дата(1,1,1)), функция вернёт понедельник, так как 01.01.0001 — формально понедельник. Это частый источник скрытых ошибок: пустая дата молча превращается в «понедельник», и логика проверки выходных срабатывает неверно. Перед вызовом стоит проверять дату на заполненность через ЗначениеЗаполнено().
Как получить название дня недели строкой
Число от 1 до 7 редко нужно пользователю — обычно требуется слово «среда» или «Ср». Есть два рабочих способа: форматная строка и собственное соответствие.
Способ 1: функция Формат с форматной строкой
Функция Формат() с конструкцией ДФ=dddd выводит полное название дня недели, а ДФ=ddd — сокращённое. Язык результата зависит от региональных настроек сеанса.
ПолноеНазвание = Формат(ДатаПроверки, "ДФ=dddd"); // "среда"
КраткоеНазвание = Формат(ДатаПроверки, "ДФ=ddd"); // "Ср"
СДатой = Формат(ДатаПроверки, "ДЛФ=DD"); // "15 мая 2026 г."
ПолнаяСтрока = Формат(ДатаПроверки, "ДФ='dddd, d MMMM yyyy'"); // "среда, 15 мая 2026"
Этот способ предпочтителен для интерфейса и печатных форм: он автоматически учитывает локализацию и не требует писать словарь названий вручную.
Способ 2: соответствие числа и строки
Если нужен фиксированный русский текст независимо от настроек сеанса (например, в обмене данными или при формировании файлов), надёжнее задать соответствие явно:
Названия = Новый Соответствие;
Названия.Вставить(1, "Понедельник");
Названия.Вставить(2, "Вторник");
Названия.Вставить(3, "Среда");
Названия.Вставить(4, "Четверг");
Названия.Вставить(5, "Пятница");
Названия.Вставить(6, "Суббота");
Названия.Вставить(7, "Воскресенье");
НазваниеДня = Названия[ДеньНедели(ДатаПроверки)];
НомерДня = ДеньНедели(ТекущаяДатаСеанса()); // 1..7
Название = Формат(ТекущаяДатаСеанса(), "ДФ=dddd"); // "среда"Проверка выходного дня и типовые условия
Самая частая прикладная задача — определить, выпадает ли дата на субботу или воскресенье. Условие строится на сравнении результата функции с числами 6 и 7:
Функция ЭтоВыходной(ПроверяемаяДата) Экспорт
Если Не ЗначениеЗаполнено(ПроверяемаяДата) Тогда
Возврат Ложь;
КонецЕсли;
Возврат ДеньНедели(ПроверяемаяДата) >= 6;
КонецФункции
На базе этой проверки строятся более сложные сценарии: перенос срока оплаты с воскресенья на понедельник, запрет создания документов отгрузки в выходные, предупреждение пользователя при выборе нерабочей даты в форме. Например, сдвиг даты на следующий понедельник, если она попала на выходные:
Пока ДеньНедели(ДатаСрока) >= 6 Цикл
ДатаСрока = ДатаСрока + 86400; // прибавляем одни сутки в секундах
КонецЦикла;
Арифметика дат в 1С выполняется в секундах: сутки — это 86400. Такой цикл безопасен, потому что гарантированно завершится максимум за две итерации.
День недели в запросах и СКД
В языке запросов 1С есть одноимённая функция ДЕНЬНЕДЕЛИ(Дата) — она также возвращает число от 1 до 7 и доступна в секциях ВЫБРАТЬ, ГДЕ, ИТОГИ и в выражениях СКД.
ВЫБРАТЬ
ДЕНЬНЕДЕЛИ(Продажи.Период) КАК НомерДня,
СУММА(Продажи.СуммаОборот) КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты КАК Продажи
СГРУППИРОВАТЬ ПО
ДЕНЬНЕДЕЛИ(Продажи.Период)
Такой запрос позволяет, например, проанализировать, в какие дни недели магазин продаёт больше всего. В отчёте на СКД номер дня можно преобразовать в название через вычисляемое поле или оформление, но проще вывести и номер, и отсортировать по нему — тогда строки отчёта пойдут от понедельника к воскресенью в естественном порядке.
Учтите: использование функции в условии ГДЕ по неиндексированному выражению отключает использование индекса по полю даты. На больших таблицах движений фильтр ГДЕ ДЕНЬНЕДЕЛИ(Период) = 6 приведёт к полному сканированию. Если такие выборки выполняются регулярно, лучше хранить номер дня недели в отдельном реквизите или измерении и индексировать его.
Сдвиг даты на рабочий день и расчёт сроков
Практический сценарий из учётных задач: договор требует оплаты «в течение 3 рабочих дней». Здесь недостаточно прибавить 3 суток — нужно пропускать субботу и воскресенье:
Функция ПрибавитьРабочиеДни(ДатаНачала, ЧислоДней) Экспорт
Результат = ДатаНачала;
Добавлено = 0;
Пока Добавлено < ЧислоДней Цикл
Результат = Результат + 86400;
Если ДеньНедели(Результат) < 6 Тогда
Добавлено = Добавлено + 1;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Эта функция корректна для простых случаев, когда достаточно пропускать только субботу и воскресенье. Если требуется учитывать праздничные дни, вместо условия ДеньНедели(Результат) < 6 нужно обращаться к производственному календарю — в типовых конфигурациях для этого есть готовые функции общих модулей работы с календарными графиками.
Обратная задача — найти начало недели для произвольной даты. Это нужно при группировке данных по неделям и при построении планов:
НачалоНедели = НачалоНедели(ДатаПроверки); // понедельник 00:00:00
КонецНедели = КонецНедели(ДатаПроверки); // воскресенье 23:59:59
Штатные функции НачалоНедели() и КонецНедели() избавляют от ручных вычислений через ДеньНедели и сдвиг даты — используйте их, они меньше подвержены ошибкам.
- 1Добавьте на форму надпись или реквизит строкового типа для отображения дня недели.
- 2В обработчике ПриИзменении поля даты вызовите: НадписьДеньНедели = Формат(Объект.Дата, "ДФ=dddd");
- 3Добавьте ту же строку в обработчик ПриСозданииНаСервере или ПриОткрытии, чтобы подпись заполнялась сразу при открытии формы.
- 4Проверьте поведение при пустой дате: при необходимости очищайте надпись, если дата не заполнена.
- 5Откройте документ и убедитесь, что при смене даты название дня обновляется корректно.
Типичные ошибки и как их проверить
Первая распространённая ошибка — путаница с нумерацией. Разработчики, пришедшие из других языков (например, JavaScript, где воскресенье — 0), ошибочно считают воскресенье первым днём и пишут условие ДеньНедели(Дата) = 1 для проверки выходного. В 1С единица — всегда понедельник.
Вторая ошибка — обработка пустой даты без проверки. Пустая дата возвращает 1, и документ без даты внезапно признаётся «понедельником». Всегда проверяйте ЗначениеЗаполнено() до вызова или осмысленно обрабатывайте этот случай.
Третья ошибка — попытка учесть праздники через ДеньНедели. Функция календарная, а не производственная: майские праздники, новогодние каникулы и перенесённые рабочие субботы она не видит. Для расчёта отпускных, больничных, сроков сдачи отчётности и платежей используйте производственный календарь.
Четвёртая ошибка — локализация строк. Если название дня получено через Формат() и потом сравнивается со строкой «Суббота», код сломается при смене языка сеанса или регистра букв. Для логики сравнивайте числа, а строки используйте только для отображения.
Проверка результата
Быстрый способ убедиться, что код работает правильно, — прогнать его на заведомо известных датах. Возьмите несколько дат, день недели которых легко сверить с любым календарём, и сравните результат функции с ожиданием. Удобно оформить это как таблицу в тестовой обработке или во внешней консоли кода.
Для прикладных решений проверяйте граничные случаи: переход через конец месяца при сдвиге даты, високосный февраль, даты, попадающие на субботу и воскресенье, и пустую дату. Если логика используется в проведении документов, прогоните тест на копии базы — ошибка в расчёте сроков в рабочей базе может привести к неверным платежам или отгрузкам.
Как проверить результат
Понедельник возвращает 1, воскресенье — 7
Воскресенье даёт 1 или 0 — перепутана система нумерации
Код явно обрабатывает незаполненную дату
Пустая дата молча трактуется как понедельник
Суббота и воскресенье переносятся на понедельник
Дата сдвигается на выходной или цикл зависает
Название соответствует календарю и языку интерфейса
Название не совпадает с реальным днём недели
FAQ
Что возвращает ДеньНедели() для пустой даты?
Для значения Дата(1,1,1) функция вернёт 1 (понедельник), потому что 1 января 0001 года формально приходится на понедельник. Это не ошибка платформы, но требует проверки даты на заполненность перед вызовом, иначе пустые даты будут молча участвовать в логике как понедельники.
Как учесть праздничные дни, а не только субботу и воскресенье?
Функция ДеньНедели этого не умеет. В типовых конфигурациях (БП, ЗУП, ERP) используйте производственный календарь — сведения о рабочих и нерабочих днях хранятся в регистре, и есть готовые программные интерфейсы для проверки дня и прибавления рабочих дней к дате.
Можно ли получить день недели в запросе без обхода результата?
Да, в языке запросов есть функция ДЕНЬНЕДЕЛИ(Дата), возвращающая число от 1 до 7. Её можно использовать в списке выбора, группировке и условиях. Для вывода названия дня в отчёте на СКД добавьте вычисляемое поле или ресурс оформления.
Почему Формат(Дата, "ДФ=dddd") выводит название на другом языке?
Язык результата определяется региональными настройками сеанса или параметром локализации форматной строки. Если нужен гарантированно русский текст независимо от настроек, задайте соответствие номера дня и строки-названия вручную.
Как найти понедельник недели, в которую попадает дата?
Используйте штатную функцию НачалоНедели(Дата) — она вернёт понедельник со временем 00:00:00. Аналогично КонецНедели(Дата) вернёт воскресенье 23:59:59. Ручной расчёт через ДеньНедели и вычитание суток не нужен.
Замедляет ли ДЕНЬНЕДЕЛИ() запрос к большой таблице?
Сама функция быстрая, но её использование в условии ГДЕ по полю даты отключает индекс по этому полю, и СУБД вынуждена сканировать всю таблицу. Решение — ограничить выборку диапазоном дат, а день недели проверять дополнительно, либо хранить номер дня в отдельном индексированном поле.
Что важно запомнить
ДеньНедели(Дата) возвращает 1–7 от понедельника к воскресенью; название дня получают через Формат с ДФ=dddd или собственное соответствие. Проверка выходных — сравнение с 6 и 7, но праздники функция не учитывает: для сроков и расчётов нужен производственный календарь. Всегда проверяйте дату на заполненность и избегайте ДЕНЬНЕДЕЛИ в условиях запросов по большим таблицам.