Разработка и Конфигурация · 11 мин
Как получить текущую дату без времени в 1С
Как получить текущую дату без времени в 1С: функции НачалоДня, ТекущаяДатаСеанса, форматирование и работа с датами в запросах. Примеры кода и типичные ошибки.
Во встроенном языке 1С тип «Дата» всегда содержит и дату, и время с точностью до секунды. Функция ТекущаяДатаСеанса() возвращает полное значение, и если его использовать напрямую для сравнения дат, вывод в документ или заполнение реквизита, в результат попадает лишнее время. Это приводит к ошибкам сравнения периодов, сбоям в запросах с отборами по дате и неправильному выводу в печатных формах.
Обнулить время можно несколькими способами: функцией НачалоДня(), форматированием строки, конструктором даты Дата() с извлечёнными компонентами, а также средствами языка запросов. Выбор зависит от контекста: нужно значение типа «Дата» для дальнейших вычислений или строка для вывода пользователю.
Ниже разобраны рабочие варианты кода, их ограничения, отличия поведения на клиенте и сервере, а также типичные ошибки, из-за которых сравнение дат даёт неожиданный результат.
Базовый способ: функция НачалоДня
Функция НачалоДня() принимает значение типа «Дата» и возвращает ту же дату с нулевым временем — 00:00:00. Это штатный и самый читаемый способ отсечь время:
ТекущаяДатаБезВремени = НачалоДня(ТекущаяДатаСеанса());
// Результат: 15.03.2026 0:00:00
Функция работает и на тонком клиенте, и на сервере, и в веб-клиенте, доступна во всех актуальных версиях платформы. Результат остаётся полноценным типом «Дата», поэтому с ним можно выполнять арифметику: добавлять дни, сравнивать, передавать в запросы как параметр.
Обратите внимание: НачалоДня() не «удаляет» время из типа данных — она устанавливает его в полночь. Если затем сравнить это значение с произвольной датой документа (у которой время, например, 14:32:17), сравнение на равенство не пройдёт. Для сравнений «в пределах дня» нужен либо отбор по диапазону, либо приведение обеих сторон к началу дня.
Получение даты строкой через Формат
Когда значение нужно для вывода пользователю, записи в строковый реквизит, имени файла или печатной формы, удобнее сразу получить строку без времени. Для этого служит функция Формат() с параметром форматной строки:
ДатаСтрокой = Формат(ТекущаяДатаСеанса(), "ДЛФ=D");
// Результат: "15.03.2026"
ДатаПрописью = Формат(ТекущаяДатаСеанса(), "ДЛФ=DD");
// Результат: "15 марта 2026 г."
Параметр ДЛФ=D задаёт локальный формат даты — короткое представление согласно региональным настройкам сеанса. ДЛФ=DD выводит длинную дату с названием месяца прописью, что удобно для договоров и писем. Если нужен фиксированный формат независимо от региональных настроек, используйте явный шаблон:
ДатаДляФайла = Формат(ТекущаяДатаСеанса(), "ДФ=yyyyMMdd");
// Результат: "20260315" — удобно для имён файлов и обменов
ДатаISO = Формат(ТекущаяДатаСеанса(), "ДФ=yyyy-MM-dd");
// Результат: "2026-03-15"
Помните, что результат Формат() — строка. Сравнивать такие строки операторами «больше/меньше» нельзя: сравнение будет лексикографическим, и «02.01.2026» окажется «больше», чем «15.12.2023». Для вычислений держите значение в типе «Дата», а форматируйте только в точке вывода.
Конструктор даты и извлечение компонентов
Альтернатива НачалоДня() — собрать новую дату из компонентов через функции Год(), Месяц(), День() и конструктор Дата():
Сейчас = ТекущаяДатаСеанса();
ДатаБезВремени = Дата(Год(Сейчас), Месяц(Сейчас), День(Сейчас));
Результат идентичен НачалоДня(), но код длиннее и медленнее читается. Такой приём оправдан, когда наряду с обнулением времени нужно изменить один из компонентов — например, получить первое число текущего месяца: Дата(Год(Сейчас), Месяц(Сейчас), 1). Впрочем, для этого тоже есть штатные функции НачалоМесяца(), НачалоКвартала(), НачалоГода() и НачалоНедели().
Семейство функций начала периода — самый безопасный путь, когда нужна граница интервала. Не вычисляйте границы вручную арифметикой: добавление 86400 секунд для перехода к следующему дню работает, но код становится хрупким и трудным для проверки.
Текущая дата без времени в запросах
В языке запросов 1С нет отдельного типа «дата без времени», поэтому задача решается двумя приёмами. Первый — передать в запрос параметр, уже приведённый к началу дня, и сравнивать с диапазоном:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Дата МЕЖДУ &НачалоДня И &КонецДня";
Запрос.УстановитьПараметр("НачалоДня", НачалоДня(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("КонецДня", КонецДня(ТекущаяДатаСеанса()));
Второй приём — применить функцию запроса НАЧАЛОПЕРИОДА() прямо к полю:
"ГДЕ
| НАЧАЛОПЕРИОДА(Реализация.Дата, ДЕНЬ) = &ТекущаяДата"
Между вариантами есть практическое различие. Отбор «МЕЖДУ» по индексированному полю даты позволяет СУБД использовать индекс и работает быстрее на больших таблицах. Применение функции НАЧАЛОПЕРИОДА к полю в условии отбора обычно отключает использование индекса по этому полю, что на объёмных документах заметно замедляет выборку. Предпочитайте передачу границ параметрами.
Сравнение вариантов
Универсально для кода. Возвращает тип Дата, пригоден для вычислений и параметров запроса
Для вывода пользователю и строковых реквизитов. Результат — строка, не подходит для сравнений
Когда одновременно меняется компонент даты, иначе избыточно
Оптимально для отборов по дню: сохраняет использование индекса
ТекущаяДатаСеанса или ТекущаяДата: что выбрать
В платформе существуют две функции получения текущего момента. ТекущаяДатаСеанса() возвращает дату и время сеанса с учётом часового пояса, установленного для информационной базы или сеанса. ТекущаяДата() возвращает дату компьютера, на котором выполняется код; на сервере в серверном контексте она недоступна в ряде режимов и в целом считается устаревшей.
Практическое правило: в прикладном коде всегда используйте ТекущаяДатаСеанса(). Это гарантирует единообразие, когда пользователи работают в разных часовых поясах, а сервер находится в другом регионе. Расхождение в дате на границе суток — классический источник ошибок «документ записан не тем числом».
Если база работает в одном часовом поясе и часовой пояс сеанса не настроен, обе функции обычно дают одинаковый результат. Но код, написанный через ТекущаяДатаСеанса(), останется корректным при переезде на распределённую инфраструктуру.
Проверка результата и отладка
Убедиться, что время действительно обнулено, проще всего выводом значения в сообщение или консоль:
ДатаБезВремени = НачалоДня(ТекущаяДатаСеанса());
Сообщить(ДатаБезВремени);
// Ожидаемый вывод: 15.03.2026 0:00:00
Если в выводе присутствуют ненулевые часы, минуты или секунды, значит, значение не прошло через НачалоДня() — проверьте, не перезаписывается ли переменная дальше по коду. Частая ситуация: разработчик приводит дату к началу дня, а затем присваивает реквизиту исходное значение документа.
Для проверки корректности сравнения дат используйте явное приведение обеих сторон: НачалоДня(Дата1) = НачалоДня(Дата2). Такой приём устраняет влияние времени и делает намерение кода очевидным для того, кто будет его сопровождать.
Как проверить результат
Время равно 0:00:00
Присутствуют ненулевые часы или минуты
НачалоДня(Дата1) = НачалоДня(Дата2) даёт Истина
Сравнение исходных значений даёт Ложь
Попадают все документы с 00:00:00 до 23:59:59
Документы с ненулевым временем отсутствуют в выборке
Частые сценарии применения
Заполнение реквизита документа текущей датой
Если реквизит имеет состав даты «Дата» (без времени), платформа сама отсекает время при записи — значение сохранится с нулевым временем. Явно вызывать НачалоДня() в этом случае не обязательно, но это улучшает читаемость и страхует от изменения состава даты реквизита в будущем.
Имя файла выгрузки
При формировании файлов обмена в имя включают дату в формате без разделителей: Формат(ТекущаяДатаСеанса(), "ДФ=yyyyMMdd"). Если в течение дня файлов несколько, добавьте время: ДФ=yyyyMMdd_HHmmss — тогда имена не перекроют друг друга.
Отбор в динамическом списке
Для динамического списка с отбором «за сегодня» задайте параметры периода через НачалоДня() и КонецДня() в обработчике ПриСозданииНаСервере формы. Использование СтандартнаяДатаНачала с вариантом «Сегодня» — альтернатива без кода, если список строится на произвольном запросе с параметрами стандартного периода.
- 1Определите, нужен результат как тип Дата или как строка
- 2Для типа Дата вызовите НачалоДня(ТекущаяДатаСеанса())
- 3Для строки примените Формат(ТекущаяДатаСеанса(), "ДЛФ=D") или шаблон ДФ
- 4В запросе передайте границы дня параметрами и используйте МЕЖДУ
- 5Проверьте результат выводом: время должно быть 0:00:00
Что важно запомнить
Тип Дата в 1С всегда содержит время, поэтому «дата без времени» — это начало дня 00:00:00 или строка. Используйте НачалоДня(ТекущаяДатаСеанса()) для значений, Формат с ДЛФ или ДФ — для вывода, параметры с МЕЖДУ — в запросах. Не сравнивайте даты строками и не забывайте про часовые пояса сеанса.
Частые вопросы
Можно ли объявить переменную типа «только дата» без времени?
Нет. Тип «Дата» в платформе всегда включает время с точностью до секунды. Ограничить состав можно только у реквизитов объектов конфигурации через свойство «Состав даты» — тогда время при записи отсекается платформой. В коде используйте НачалоДня().
Почему сравнение НачалоДня(ТекущаяДатаСеанса()) с датой документа даёт Ложь?
Дата документа почти всегда содержит ненулевое время. Сравнивайте либо НачалоДня() от обеих сторон, либо проверяйте вхождение даты документа в диапазон от НачалоДня() до КонецДня() текущей даты.
Чем отличается ДЛФ от ДФ в функции Формат()?
ДЛФ — локальный формат даты, зависящий от региональных настроек сеанса (D — краткая дата, DD — длинная). ДФ — явный шаблон с кодами (yyyy, MM, dd), результат которого одинаков в любых настройках. Для обменов и имён файлов используйте ДФ, для интерфейса — ДЛФ.
Как получить вчерашнюю или завтрашнюю дату без времени?
Прибавьте или вычтите сутки в секундах: НачалоДня(ТекущаяДатаСеанса() - 86400) для вчерашней даты и НачалоДня(ТекущаяДатаСеанса() + 86400) для завтрашней. Сначала арифметика, затем приведение к началу дня.
Работает ли НАЧАЛОПЕРИОДА в запросе с параметром-виртуальной таблицей?
Да, функция НАЧАЛОПЕРИОДА доступна в условиях, полях выборки и параметрах виртуальных таблиц. Однако для отборов по периоду виртуальных таблиц регистров предпочтительнее передавать границы параметрами Период/НачалоПериода и КонецПериода — это эффективнее по производительности.
Что вернёт ТекущаяДатаСеанса(), если часовой пояс сеанса не задан?
Будет использован часовой пояс по умолчанию: для файловой базы — пояс компьютера, для клиент-серверной — пояс сервера либо настройка информационной базы. Проверить текущий пояс можно функцией ПолучитьЧасовойПоясИнформационнойБазы() или ЧасовойПоясСеанса().