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

Существует множество способов получить этот параметр: от встроенных функций языка запросов до методов глобального контекста. Выбор конкретного метода зависит от того, где именно выполняется код — в обработке, в отчете СКД или непосредственно в модуле объекта. Неправильный выбор метода может привести к снижению производительности системы, особенно при обработке больших массивов данных.

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

Использование встроенной функции День()

Самым очевидным и часто используемым способом является применение встроенной функции День(). Эта функция принимает на вход значение типа Дата и возвращает целое число от 1 до 31, соответствующее дню месяца. Она доступна во всех контекстах выполнения кода 1С, что делает её универсальным инструментом для разработчика.

При использовании в модуле формы или общего модуля синтаксис предельно прост. Вам достаточно передать переменную с датой в качестве аргумента. Это поведение гарантирует предсказуемый результат независимо от времени записи в базе данных.

Рассмотрим пример кода, демонстрирующий работу функции в обычном модуле:

ТекущаяДата = ТекущаяДата();

НомерДня = День(ТекущаяДата);

Сообщить("Сегодня " + НомерДня + " число");

Однако, если вы работаете в языке запросов, синтаксис немного меняется, хотя суть остается прежней. В тексте запроса функция вызывается напрямую в списке полей. Это позволяет фильтровать или группировать данные сразу на стороне сервера баз данных, что существенно быстрее, чем выборка всех записей и их последующая обработка в коде 1С.

💡

Использование функции День() непосредственно в запросе снижает нагрузку на клиентское приложение, так как вычисление происходит на стороне СУБД.

Стоит отметить, что функция День() возвращает именно числовое значение. Если ваша задача заключается в форматировании строки, например, для вывода в печатную форму с ведущим нулем (01, 02, 05), то одного вызова функции будет недостаточно. В таких случаях потребуется дополнительное форматирование результата.

Извлечение дня в языке запросов 1С

Работа с датами в запросах имеет свои особенности, которые критически важны для производительности системы. Когда вы пишете запрос к регистру накопления или документу, использование функции День() в условии отбора (секция ГДЕ) может привести к полному сканированию таблицы, если не используются специальные приемы.

Для эффективной выборки данных за конкретный день лучше использовать границы периода. Вместо проверки равенства дня, следует ограничить диапазон дат от начала дня до конца дня. Для этого в языке запросов предусмотрены специальные функции НАЧАЛОДНЯ() и КОНЕЦДНЯ().

Пример корректного построения запроса для выборки документов за определенное число:

ВЫБРАТЬ

ДокументРеализация.Ссылка,

ДокументРеализация.Дата

ИЗ

Документ.РеализацияТоваровУслуг КАК ДокументРеализация

ГДЕ

ДокументРеализация.Дата МЕЖДУ &НачалоДня И &КонецДня

В параметрах запроса при этом передаются значения, рассчитанные заранее:

  • 📅 &НачалоДня = НачалоДня(ВыбраннаяДата)
  • 🏁 &КонецДня = КонецДня(ВыбраннаяДата)
  • ⚡ Это позволяет использовать индексы по полю Дата
  • 📉 Запрос выполняется мгновенно даже на больших объемах

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

📊 Где вы чаще всего используете извлечение дня?
В отчетах СКД
В модуле объекта
В языке запросов
В печатных формах

В системах управления базами данных, таких как MS SQL Server или PostgreSQL, которые используются как серверы для 1С, подобные функции также существуют. Однако платформа 1С абстрагирует разработчика от диалектов SQL, предоставляя единый синтаксис. Это гарантирует, что ваш код будет работать одинаково эффективно на любой поддерживаемой СУБД без необходимости переписывания.

Работа с началом и концом дня

Часто задача "выбрать день" на самом деле подразумевает работу с временным интервалом, охватывающим эти сутки целиком. В 1С дата всегда хранится вместе с временем. Если время не указано явно, оно считается равным нулю (начало дня). Это фундаментальное правило, нарушение которого приводит к ошибкам логики.

Функция НАЧАЛОДНЯ() возвращает дату с обнуленным временем (00:00:00). Это идеальный инструмент для приведения произвольной даты к началу суток. Например, если пользователь выбрал в интерфейсе дату и время "15.05.2026 14:30", применение функции вернет "15.05.2026 00:00".

⚠️ Внимание: Прямое сравнение даты документа с датой, введенной пользователем, часто приводит к ошибкам. Документ может быть проведен в 23:59, а пользователь ввел дату без времени. Такое сравнение вернет Ложь, хотя документ относится к этому дню.

Для получения конца дня используется функция КОНЕЦДНЯ(). Она возвращает дату, соответствующую 23:59:59 указанного дня. Использование пары этих функций позволяет корректно охватить весь временной диапазон суток в условиях отбора.

Рассмотрим таблицу основных функций работы с периодами в 1С:

Функция Описание Пример результата для 15.05.2026 12:00
НачалоДня() Усекает время до нуля 15.05.2026 00:00:00
КонецДня() Устанавливает время на конец суток 15.05.2026 23:59:59
День() Возвращает число месяца 15
Месяц() Возвращает номер месяца 5

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

Почему в 1С время 23

59:59, а не 24:00:00?:В большинстве СУБД и в стандарте ISO 8601 сутки заканчиваются в момент 23:59:59.999, после чего наступает 00:00:00 следующего дня. Понятие 24 часа используется только в разговорной речи, но не в машинном представлении времени.

Форматирование даты для вывода числа

Когда речь заходит о пользовательском интерфейсе или печатных формах, часто требуется представить день не как число, а как часть строки. Например, для вывода в формате "15 мая 2026" или просто "15". В таких случаях на помощь приходит механизм Форматирования.

Функция Формат() позволяет гибко управлять представлением даты. Используя строку формата, можно указать, какие компоненты даты должны быть отображены. Для вывода только дня используется спецификатор Ч (число) или Д (день с ведущим нулем).

Пример использования в коде:

ДатаДокумента = ТекущаяДата();

СтрокаДня = Формат(ДатаДокумента, "Ч"); // Вернет "5" для 5-го числа

СтрокаДняСНулем = Формат(ДатаДокумента, "Д"); // Вернет "05"

В макетах компоновки данных (СКД) настройка формата производится через свойства поля. В конструкторе формата можно выбрать опцию "День" и указать необходимость вывода ведущего нуля. Это избавляет от необходимости писать дополнительный код в модуле объекта.

⚠️ Внимание: Локальные настройки пользователя могут влиять на разделители и порядок вывода, но спецификаторы формата в 1С работают независимо от региональных настроек ОС, если явно не задан иной язык формата.

Также стоит упомянуть о возможности получения названия дня недели. Хотя это не является прямым извлечением "числа", часто эти задачи решаются в одном контексте. Спецификатор ДН позволяет получить сокращенное или полное название дня недели, что полезно для визуализации календарей.

💡

Используйте функцию Формат() для представления данных пользователю, а функцию День() для логических вычислений и условий.

Обработка ошибок и некорректных данных

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

Для предотвращения аварийной остановки программы необходимо всегда проверять тип значения перед вызовом функций работы с датой. В языке 1С для этого используется оператор ТипЗнч() или конструкция Если ЗначениеЗаполнено().

Пример безопасного получения дня:

Если ТипЗнч(ВходящаяДата) = Тип("Дата") Тогда

НомерДня = День(ВходящаяДата);

Иначе

НомерДня = 0; // Или другое значение по умолчанию

КонецЕсли;

Особое внимание следует уделить данным, импортируемым из внешних источников (текстовые файлы, XML, JSON). Часто даты могут приходить в строковом формате, который система не распознает автоматически. В таких случаях необходимо предварительно конвертировать строку в тип Дата с помощью функции Дата() или ПолучитьДатуИзСтроки().

  • ✅ Всегда проверяйте тип данных перед вычислениями
  • 🛡 Обрабатывайте исключения в критических участках кода
  • ⚠ Не полагайтесь на автоматическое преобразование типов из внешних систем

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

☑️ Проверка даты перед обработкой

Выполнено: 0 / 4

Оптимизация производительности при работе с датами

В высоконагруженных системах 1С каждая миллисекунда на счету. Неправильное использование функций даты в запросах может превратить быстрый отчет в процесс, длящийся минуты и часы. Главная причина — потеря возможности использования индексов.

Если вы применяете функцию к полю в условии ГДЕ, например ГДЕ День(Регистр.Дата) = 15, оптимизатор запросов часто не может использовать индекс по полю Дата. Вместо точечного обращения к нужным записям, система вынуждена перебирать весь регистр, вычисляя день для каждой строки. Это явление называется "полным сканированием таблицы".

Для решения этой проблемы следует использовать диапазон значений, как описывалось в разделе про язык запросов. Переписав условие на ГДЕ Регистр.Дата МЕЖДУ НачалоДня(..) И КонецДня(..), вы позволяете СУБД использовать индекс для мгновенного поиска нужного диапазона.

В табличных документах и отчетах, где строк может быть десятки тысяч, избегайте вызовов функций даты в цикле по каждой строке макета. Лучше подготовить все данные в одном запросе, включив туда вычисленный день как отдельное поле, и затем просто выводить готовое значение.

⚠️ Внимание: Интерфейс и логика работы с датами могут незначительно отличаться в различных конфигурациях (Бухгалтерия, ЗУП, УТ) и версиях платформы. Всегда сверяйтесь с актуальной синхронизацией вашей конфигурации и платформы перед внедрением сложных алгоритмов.

Также стоит учитывать часовой пояс при работе с распределенными базами или веб-сервисами. Дата, сохраненная в базе в UTC, при отображении пользователю в другом часовом поясе может сдвинуться на предыдущий или следующий день. Функции 1С работают с локальным временем клиента, если не указано иное, но при обмене данными этот нюанс нужно держать в голове.

Как часовой пояс влияет на День()?

Если сервер находится в Москве, а пользователь во Владивостоке, и дата сохранена как универсальная, то при вызове День() на клиенте может вернуться другое число, чем на сервере, из-за разницы во времени наступления полуночи.

Часто задаваемые вопросы (FAQ)

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

Для этого можно использовать функцию КонецМесяца(). Передайте в нее любую дату интересующего месяца, а затем примените функцию День() к результату. Например: День(КонецМесяца(Дата)) вернет 30 или 31 в зависимости от месяца.

Почему функция День() возвращает 0 или ошибку?

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

Можно ли извлечь день из строки "25.12.2023" без преобразования в дату?

Технически можно использовать функции работы со строками (СтрЗаменить, СтрПолучитьПодстроку), но это ненадежно из-за разных форматов дат. Правильный путь — сначала преобразовать строку в тип Дата функцией ПолучитьДатуИзСтроки(), а затем использовать День().

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

В секции СГРУППИРОВАТЬ ПО укажите День(Документ.Дата). Однако помните, что это сгруппирует все 15-е числа всех месяцев вместе. Если нужна группировка по конкретной дате, группируйте по НачалоДня(Документ.Дата).

Влияет ли версия платформы 1С на работу функций даты?

Базовые функции День(), Месяц(), Год() работают одинаково во всех актуальных версиях платформы 8.2, 8.3 и выше. Различия могут касаться только тонкостей работы с часовыми поясами в веб-клиенте или новых спецификаторов формата в последних релизах.