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

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

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

Специфика типа данных Дата в 1С

В системе 1С:Предприятие тип данных Дата хранится как количество секунд, прошедших с начала эры (1 января 0001 года). Это означает, что любое значение даты технически всегда содержит информацию о времени суток. Даже если в интерфейсе отображается «01.01.2026», внутри переменной может храниться «01.01.2026 14:35:10».

Для корректной работы алгоритмов часто требуется нормализовать значение, отбросив минуты, секунды и часы. Это критически важно при группировке данных или сравнении периодов. Если вы попытаетесь сравнить две даты, одна из которых имеет время 00:00:00, а другая 23:59:59, условие равенства вернет Ложь, хотя визуально даты совпадают.

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

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

💡

Используйте функцию НачалоДня вместо ручного вычитания времени — это делает код более читаемым и защищает от ошибок при переходе через летнее/зимнее время.

Использование функции НачалоДня

Самый надежный и рекомендуемый способ получить дату без времени — это использование встроенной функции НачалоДня. Она принимает значение типа Дата и возвращает новую дату, у которой время установлено в 00:00:00. Это стандарт де-факто в современной разработке на 1С.

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

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

ДатаБезВремени = НачалоДня(ТекущаяДата);

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

  • 📅 Функция автоматически учитывает переходы между часовыми поясами, если они настроены в системе.
  • ⚡ Операция выполняется крайне быстро и не создает лишней нагрузки на процессор.
  • 🛡️ Защищает код от ошибок, связанных с ручным расчетом секунд в сутках.

Использование НачалоДня особенно актуально при формировании периодов отчетов. Например, если пользователь выбрал дату «Сегодня», вы должны начать выборку данных с 00:00:00 этого дня, а не с текущего момента, чтобы не потерять документы, проведенные утром.

📊 Какой метод вы используете чаще всего?
НачалоДня
Ручной расчет секунд
Функция в запросе
Не задумывался об этом

Альтернативные методы: НачалоПериода и математика

Помимо НачалоДня, в языке существует функция НачалоПериода, которая является более универсальной. Она позволяет получить начало любого периода: дня, месяца, квартала или года. Для задачи «дата без времени» мы используем параметр Период.День.

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

Существует также «старый» метод, основанный на математических вычислениях. Поскольку в сутках 86400 секунд, можно вычислить остаток от деления количества секунд на это число и вычесть его из исходной даты. Такой подход считается устаревшим и менее читаемым:

СекундВДне = 86400;

ОстатокВремени = ТекущаяДата % СекундВДне;

ДатаБезВремени = ТекущаяДата - ОстатокВремени;

⚠️ Внимание: Ручные математические операции с датами могут привести к ошибкам при работе с високосными годами или специфическими настройками календаря. Используйте встроенные функции платформы.

Еще один вариант — использование функции Год, Месяц и День для конструирования новой даты через Дата. Это создает новую переменную с нуля, игнорируя время исходного значения. Метод рабочий, но более громоздкий по сравнению с НачалоДня.

Почему не стоит использовать строковые функции?

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

Работа с датами в запросах 1С

При написании запросов к базе данных ситуация немного отличается от кода модулей. В языке запросов 1С также доступна функция НАЧАЛОПЕРИОДА. Это единственный корректный способ получить дату без времени непосредственно внутри текста запроса.

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

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

ВЫБРАТЬ

Документ.Ссылка,

НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) КАК ДатаБезВремени

ИЗ

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

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

Функция в запросе Параметр периода Результат Производительность
НАЧАЛОПЕРИОДА ДЕНЬ 00:00:00 текущего дня Высокая (индексируется)
НАЧАЛОПЕРИОДА МЕСЯЦ 00:00:00 первого числа Высокая
Ручная математика Зависит от формулы Низкая (тормозит запрос)
ГОД/МЕСЯЦ/ДЕНЬ Конструирование даты Средняя

При использовании параметров в запросах (через объект ПостроительЗапроса или Выполнить) рекомендуется передавать уже обработанную дату из кода 1С, если это возможно. Это упрощает текст запроса и делает его более переносимым.

💡

Всегда выполняйте обрезку времени внутри запроса с помощью НАЧАЛОПЕРИОДА, если используете эту дату для ГРУППИРОВКИ или ОТБОРА. Это гарантирует использование индексов базы данных.

Сравнение дат и временные интервалы

Одна из самых частых ошибок — попытка проверить вхождение даты в интервал без учета времени. Допустим, вам нужно найти все документы за конкретный день. Если вы зададите условие Дата = &Период, где период имеет время 15:00, вы не найдете документы, проведенные в 09:00.

Правильный подход заключается в использовании полуоткрытого интервала. Вы берете начало дня (00:00:00) как нижнюю границу и начало следующего дня как верхнюю границу. Это покрывает весь диапазон от 00:00:00 до 23:59:59.999.

Алгоритм построения такого интервала выглядит так:

  • 🔽 Нижняя граница: НачалоДня(ИсходнаяДата)
  • 🔼 Верхняя граница: НачалоДня(ИсходнаяДата) + 86400 (или КонецДня)
  • ✅ Условие: Дата >= Начало И Дата < Конец

Использование строгого неравенства (<) для верхней границы критически важно. Если вы используете <= КонецДня, вы можете пропустить документы, созданные в последнюю миллисекунду дня, или, наоборот, захватить лишние, если функция КонецДня возвращает время 23:59:59, а документ создан в 23:59:59.500.

⚠️ Внимание: При работе с высоконагруженными системами избегайте функций в левой части условия отбора (например, НАЧАЛОПЕРИОДА(Дата) =...). Это отключает использование индексов. Лучше сдвигать границы интервала в параметрах.

Для проверки равенства двух дат игнорируя время, всегда приводите обе даты к началу дня перед сравнением. Сравнение НачалоДня(Дата1) = НачалоДня(Дата2) даст корректный результат независимо от того, в какое время были созданы объекты.

☑️ Проверка корректности интервала

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

Особенности работы с моментом времени

Тип МоментВремени часто путают с обычной Датой. Основное отличие в том, что МоментВремени привязан к конкретной временной зоне и используется для синхронизации времени между клиентами и сервером. При конвертации МоментВремени в Дата временная зона может сдвинуть значение.

Если ваша задача — получить дату без времени из МоментВремени, сначала выполните преобразование типа. После этого применяйте стандартные функции. Игнорирование этого шага может привести к тому, что «начало дня» сместится на предыдущий или следующий день из-за разницы в часовых поясах.

В современных версиях платформы 1С (8.3.10 и выше) работа с временными зонами стала более явной. Разработчик должен явно указывать, в какой зоне интерпретировать время. Функция НачалоДня применительно к МоментВремени вернет начало дня в той зоне, к которой привязан момент.

Рекомендуется хранить в базе данных обычные значения типа Дата, если не требуется глобальная синхронизация между географически распределенными филиалами с разным временем. Это упрощает логику «обрезки» времени и избавляет от лишних преобразований типов.

Частые ошибки и оптимизация кода

Одной из распространенных проблем является создание лишних объектов в цикле. Если вы обрабатываете тысячу документов и внутри цикла вызываете функции конвертации или создаете новые даты через конструктор, это может замедлить работу. Функция НачалоДня оптимизирована и безопасна для использования в циклах.

Однако стоит избегать избыточных проверок. Нет смысла вызывать НачалоДня, если вы уверены, что дата уже пришла обнуленной (например, из справочника, где время не ведется). Но в случае с документами, где время проведения обязательно, проверка необходима.

Также стоит упомянуть о функции ПолучитьНачалоДня (в некоторых контекстах или старых версиях), которая может вести себя иначе. Всегда сверяйтесь с синтаксис-помощником вашей версии платформы. В актуальных релизах стандартом является именно НачалоДня.

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

Миф о хранении даты как строки

Некоторые разработчики пытаются хранить дату без времени в строковом поле (виде"20260101"). Это грубая ошибка. Вы теряете возможность использовать встроенные календари, арифметику дат и эффективную индексацию числовых значений СУБД. Всегда используйте тип Дата.

Можно ли просто присвоить время 0 вручную?

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

Влияет ли обрезка времени на производительность запроса?

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

Что делать, если дата пришла из внешней системы в формате строки?

Сначала преобразуйте строку в тип Дата с помощью Дата или СтрокаВДату. После этого сразу примените НачалоДня, чтобы нормализовать значение перед дальнейшей обработкой или записью в базу.

Есть ли разница между НачалоДня и НачалоПериода(День)?

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