В процессе разработки конфигураций на платформе 1С:Предприятие, будь то сложная система управления производством или простая обработка документов, часто возникает необходимость анализа временных меток. Одной из базовых, но критически важных задач является определение дня недели для конкретной даты. Это требуется повсеместно: от расчета графика работы сотрудников до блокировки проведения документов в выходные дни или формирования специфических отчетов.
Платформа 1С предоставляет разработчику мощный инструментарий для работы с типом данных Дата. Вы можете получить номер дня недели, его текстовое представление или даже использовать готовые функции для календарных расчетов. Понимание различий между встроенными функциями языка и методами объектов позволяет писать более эффективный и читаемый код.
Рассмотрим основные способы решения этой задачи, начиная от простых встроенных функций и заканчивая методами форматирования вывода для пользовательского интерфейса. Правильный выбор метода зависит от того, что именно нужно системе: числовое значение для логики или красивая строка для печатной формы.
Встроенная функция ДеньНедели
Самым простым и быстрым способом получить номер дня недели является использование встроенной глобальной функции ДеньНедели(). Эта функция принимает один аргумент — дату, и возвращает целое число от 1 до 7. Нумерация в 1С традиционно начинается с понедельника, что соответствует стандарту ISO 8601, принятому в деловом обороте России.
Использование этой функции идеально подходит для программной логики, где требуется принятие решений на основе дня. Например, если вам нужно запретить создание накладных в субботу или воскресенье, проверка числового значения будет наиболее производительным решением. Числа обрабатываются быстрее, чем строковые сравнения.
Значение 1 соответствует понедельнику, а 7 — воскресенью. Это нужно учитывать при написании условных операторов. Ошибка в нумерации может привести к тому, что система начнет блокировать работу в будние дни или, наоборот, пропускать операции в выходные.
Для наглядности приведем пример кода, который демонстрирует работу функции:
ТекущаяДата = ТекущаяДата();
НомерДня = ДеньНедели(ТекущаяДата);
Если НомерДня = 6 Или НомерДня = 7 Тогда
Сообщить("Сегодня выходной день!");
Иначе
Сообщить("Сегодня рабочий день.");
КонецЕсли;
⚠️ Внимание! Функция
ДеньНедели()не зависит от настроек локали пользователя или региональных параметров системы. Она всегда возвращает число согласно стандарту платформы, где неделя начинается с понедельника.
При проверке диапазонов дней (например, с понедельника по пятницу) удобнее использовать операторы сравнения, чем перечислять каждое число: Если НомерДня < 6 Тогда..
Форматирование даты для отображения
Часто перед разработчиком стоит задача не просто вычислить день, а красиво отобразить его пользователю в интерфейсе или печатной форме. В таких случаях использование числовых значений неудобно, так как требует дополнительной расшифровки. Для решения этой проблемы в языке 1С существует мощная функция Формат().
Функция форматирования позволяет преобразовать дату в строку с указанием дня недели на любом языке, поддерживаемом платформой. Вы можете получить как полное название ("Понедельник"), так и сокращенное ("Пн"). Это достигается за счет использования специальных строковых параметров формата.
Основной параметр, отвечающий за день недели, называется ДФ (Дата Формат). Внутри строки формата используются специальные символы: Д для дня месяца, М для месяца, и, что важно для нас, ДН или ДД для дней недели. Синтаксис позволяет гибко настраивать вывод.
Рассмотрим примеры использования функции для получения различных вариантов названия дня:
- 📅
Формат(Дата, "ДФ=ДДДД")— вернет полное название дня, например "Вторник". - 📅
Формат(Дата, "ДФ=ДД")— вернет сокращенное название, например "Вт". - 📅
Формат(Дата, "ДФ=ДД ДДММГГГГ")— сформирует строку вида "Пт 25.10.2026".
Особенность функции Формат() заключается в том, что она учитывает локаль пользователя. Если система настроена на английский язык, то вместо "Понедельник" функция вернет "Monday". Это делает её незаменимой для многонациональных компаний или конфигураций, работающих в разных странах.
Методы объекта Типа Дата
В современных версиях платформы 1С:Предприятие 8 работа с датами стала более объектно-ориентированной. Тип данных Дата обладает собственными методами, которые позволяют извлекать различные составляющие временной метки без вызова глобальных функций. Это улучшает читаемость кода и соответствует современным стандартам разработки.
Для получения дня недели можно использовать метод ДеньНедели(), вызываемый непосредственно у объекта даты. Синтаксически это выглядит очень лаконично: МояДата.ДеньНедели(). Результат работы метода идентичен результату глобальной функции — целое число от 1 до 7.
Использование методов объекта предпочтительно в ситуациях, когда у вас уже есть переменная типа Дата и вы выполняете серию операций над ней. Это позволяет избежать передачи аргументов в глобальные функции и делает цепочки вызовов более понятными. Кроме того, такой подход упрощает рефакторинг кода в будущем.
В таблице ниже приведено сравнение способов получения дня недели через различные подходы:
| Способ | Синтаксис | Тип результата | Особенности |
|---|---|---|---|
| Глобальная функция | ДеньНедели(Дата) |
Число | Классический подход, работает во всех версиях |
| Метод объекта | Дата.ДеньНедели() |
Число | Современный стиль, удобен в цепочках |
| Функция Формат | Формат(Дата, "ДФ=ДДДД") |
Строка | Зависит от локали, удобно для вывода |
Выбор между глобальной функцией и методом объекта часто является вопросом вкуса команды разработчиков. Однако в новых проектах рекомендуется придерживаться объектного стиля, так как он лучше масштабируется и легче воспринимается при чтении сложных алгоритмов.
⚠️ Внимание! Методы объекта Дата появились в относительно новых версиях платформы. Если вы поддерживаете конфигурацию, которая должна работать на очень старых релизах (до 8.3.х), используйте глобальную функцию для обеспечения совместимости.
Расчет рабочих и выходных дней
Определение дня недели часто является лишь первым шагом в более сложной бизнес-логике, связанной с производственным календарем. Простая проверка на субботу и воскресенье недостаточна для реального бизнеса, так как существуют переносы праздничных дней и официальные государственные праздники.
В типовой конфигурации 1С:Бухгалтерия или 1С:ЗУП для этих целей используется объект ПроизводственныйКалендарь. Он позволяет точно определить, является ли конкретная дата рабочим днем, учитывая все официальные переносы и праздники, загруженные в базу. Это критически важно для расчета зарплаты и сроков сдачи отчетности.
Если в вашей самописной конфигурации нет объекта ПроизводственныйКалендарь, вам придется реализовывать логику вручную. Обычно это делается с помощью справочника "Праздничные дни", где хранятся даты, которые следует считать нерабочими, независимо от дня недели. Алгоритм проверки в таком случае усложняется.
Пример логики проверки рабочего дня с учетом справочника праздников:
Функция ЭтоРабочийДень(ПроверяемаяДата)
// Сначала проверяем день недели
Если ДеньНедели(ПроверяемаяДата) > 5 Тогда
Возврат Ложь; // Суббота или Воскресенье
КонецЕсли;
// Затем проверяем справочник праздников
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Праздники.Дата КАК Дата
|ИЗ
| Справочник.ПраздничныеДни КАК Праздники
|ГДЕ
| Праздники.Дата = &Дата";
Запрос.УстановитьПараметр("Дата", ПроверяемаяДата);
Если Не Запуст
Почему нельзя полагаться только на ДеньНедели?
Государственные праздники могут выпадать на будние дни, делая их выходными. Также бывают случаи, когда суббота или воскресенье объявляются рабочими днями для переноса праздников.
Особенности работы с периодами времени
При работе с отчетами часто требуется группировка данных по дням недели за определенный период. Например, менеджеру может быть интересно видеть продажи только по пятницам за последний квартал. В таких случаях использование простых циклов может быть неэффективным, и на помощь приходят возможности языка запросов 1С.
В языке запросов также доступна функция ДЕНЬНЕДЕЛИ(). Вы можете использовать её в условиях отбора (ГДЕ) или в списке полей для группировки. Это позволяет переложить вычислительную нагрузку на сервер базы данных, что значительно ускоряет формирование отчетов на больших объемах данных.
Пример запроса, выбирающего документы, проведенные только в рабочие дни:
ВЫБРАТЬ
ДокументРеализация.Ссылка,
ДокументРеализация.Дата
ИЗ
Документ.РеализацияТоваровУслуг КАК ДокументРеализация
ГДЕ
ДЕНЬНЕДЕЛИ(ДокументРеализация.Дата) < 6
Использование функции в запросе имеет свои нюансы. Сервер 1С транслирует этот вызов в соответствующую функцию СУБД (MS SQL, PostgreSQL, Oracle). Хотя логика работы в большинстве случаев совпадает, рекомендуется тестировать запросы на целевой СУБД, особенно если планируется миграция между разными системами управления базами данных.
⚠️ Внимание! При работе с временными зонами учитывайте, что день недели может измениться при конвертации времени. Дата, сохраненная в UTC, может соответствовать вчера или завтра в локальном времени пользователя.
☑️ Проверка корректности расчета дней
Частые ошибки разработчиков
Несмотря на кажущуюся простоту задачи, разработчики часто допускают ошибки при работе с днями недели. Одна из самых распространенных проблем — путаница в нумерации. В некоторых иностранных библиотеках и языках программирования неделя начинается с воскресенья (0 или 1), тогда как в 1С стандартом является понедельник.
Другая частая ошибка связана с типами данных. Попытка сравнить результат функции ДеньНедели() со строкой "Понедельник" всегда вернет ложь, так как функция возвращает число. Такие ошибки трудно отловить на этапе компиляции, но они приводят к некорректной логике работы программы в runtime.
Также стоит быть осторожным при использовании устаревших методов работы с датами, которые могли существовать в 1С 7.7. В современной платформе 8.x подход к датам унифицирован, и использование старых приемов может привести к потере производительности или ошибкам совместимости.
Для избежания ошибок рекомендуется всегда явно приводить типы данных и использовать константы или перечисления, если логика программы сильно зависит от конкретных дней. Это делает код самодокументируемым и снижает риск опечаток.
Всегда проверяйте, начинается ли неделя с понедельника в вашей логике, особенно если вы интегрируете 1С с внешними системами, где стандарты могут отличаться.
Как получить название дня недели на английском языке в 1С?
Для получения названия на английском языке используйте функцию Формат() с указанием параметра локализации. Пример: Формат(Дата, "ДФ=ДДДД; Л=en"). Параметр Л= задает язык представления. Также язык может определяться настройками пользователя в системе.
Можно ли изменить начало недели в 1С на воскресенье?
Нет, внутренняя логика платформы 1С:Предприятие жестко задает начало недели с понедельника для функции ДеньНедели(). Изменить это поведение на уровне платформы нельзя. Если бизнес-логика требует начала недели с воскресенья, необходимо делать программный сдвиг: прибавлять или вычитать 1 из полученного номера с учетом циклического перехода.
Как узнать номер недели в году?
Для получения номера недели используется функция НомерНедели(Дата). Она возвращает номер недели согласно стандарту ISO 8601. Первая неделя года — это неделя, содержащая первый четверг года. Это может отличаться от календарного представления, где первая неделя начинается 1 января.
Работает ли функция ДеньНедели с пустой датой?
Нет, передача неопределенной даты (Неопределено) или даты нулевого значения в функцию ДеньНедели() вызовет ошибку выполнения. Перед вызовом функции всегда необходимо проверять дату на заполненность с помощью оператора ЗначениеЗаполнено().
Влияет ли часовой пояс на определение дня недели?
Да, влияет. Если дата хранится в формате UTC, а пользователь находится в часовом поясе, где время отличается более чем на разницу до полуночи, день недели может измениться. При конвертации времени всегда учитывайте смещение часового пояса перед определением дня недели.