При разработке в среде «1С:Предприятие» программисты часто сталкиваются с ситуацией, когда при выгрузке данных из табличной части документа или обработки в коллекцию ТаблицаЗначений у реквизитов с типом Дата (для которых в конфигураторе задан состав даты «Дата») внезапно появляется временная часть в виде 00:00:00. На первый взгляд это кажется ошибкой платформы или неправильным поведением метода Выгрузить(). В этой статье мы подробно разберем, почему так происходит, какие подводные камни скрывают в себе очевидные решения и как правильно справиться с этой задачей в зависимости от ваших целей.
Для начала давайте проанализируем, как устроена работа с датами в 1С. В платформе «1С:Предприятие 8» примитивный тип данных Дата является комбинированным. Он всегда содержит в себе как календарную дату, так и время (с точностью до секунды). Физически в СУБД (будь то MS SQL Server, PostgreSQL или файловая база данных) и в оперативной памяти компьютера переменная этого типа не может существовать без времени.
Когда в конфигураторе для реквизита мы выбираем состав даты:
00:00:00 (ровно полночь).01.01.0001.Таким образом, полностью «стереть» время или заставить переменную типа Дата в отладчике выглядеть строго как 12.05.2026 без временной части технически невозможно. Значение 12.05.2026 00:00:00 — это и есть представление «просто даты» в системе 1С.
В ходе обсуждения на форуме был предложен вариант с явным указанием квалификаторов даты при создании колонки таблицы значений:
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Дата"));
ПараметрыДаты = Новый КвалификаторыДаты(ЧастиДаты.Дата);
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("ДатаНачала", Новый ОписаниеТипов(МассивТипов, , , ПараметрыДаты));
Автор темы попытался применить этот код, но написал, что метод «не сработал», поскольку время 00:00:00 все равно осталось в колонке. Выясним причину этого заблуждения.
На самом деле код сработал абсолютно верно и корректно. Квалификатор ЧастиДаты.Дата гарантирует, что при попытке записать в эту колонку дату со временем (например, 15.04.2026 14:30:15), платформа автоматически «отсечет» время, превратив его в 15.04.2026 00:00:00. Но поскольку тип данных остался Дата, платформа все равно отображает дефолтное нулевое время в отладчике и при стандартном выводе через функцию Сообщить(). Автор ожидал увидеть полное отсутствие символов времени, что невозможно для данного типа данных.
Кроме того, важно знать особенность работы метода Выгрузить(). При вызове Объект.Этапы.Выгрузить() платформа 1С автоматически создает таблицу значений, колонки которой полностью наследуют типы и квалификаторы из метаданных исходной табличной части. Если в свойствах реквизита ТЧ в конфигураторе уже был выбран состав «Дата», то колонка выгруженной ТЗ автоматически получит ограничение ЧастиДаты.Дата. Дополнительно переопределять её вручную программным кодом не имеет смысла.
В качестве быстрого решения на форуме предложили обходить табличную часть циклом и преобразовывать дату в строку нужного формата:
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("ДатаНачала", , "ДатаНачала");
// Добавление остальных колонок...
Для Каждого СтрокаТч Из Объект.Этапы Цикл
ТЗДобавить = ТЗ.Добавить();
ТЗДобавить.ДатаНачала = Формат(СтрокаТч.ДатаНачала, "ДЛФ=D");
// Заполнение остальных колонок...
КонецЦикла;
Этот способ действительно убирает «визуальное» время, так как в колонку записывается обычная строка (например, "15.04.2026"). Однако использование строкового представления дат во внутренних таблицах значений — это плохая практика разработки, которая может привести к серьезным ошибкам в бизнес-логике:
"01.12.2025" окажется выше (раньше), чем "02.01.2026", так как первый символ "0" и второй "1" меньше, чем "0" и "2". Это полностью ломает логику хронологических отчетов.Свернуть(), строковые представления дат могут группироваться некорректно при наличии разных региональных настроек сеанса.Давайте рассмотрим, как правильно решать проблему отображения даты без времени в зависимости от того, для чего именно вам требуются эти данные.
Если ваша единственная цель — вывести данные на печать в табличный документ или отобразить их пользователю на форме, то преобразовывать дату в коде не нужно. Оставьте значение полноценной датой, а форматирование доверьте механизмам представления платформы.
Рассмотрим, как настроить формат вывода даты в ячейке макета табличного документа:
<p>ТекущаяДата</p>).ДЛФ=D или задайте собственный шаблон в поле «Форматная строка», например, ДФ=dd.MM.yyyy).Если вы выводите данные программно, вы можете задать формат ячейки прямо в коде формирования печатной формы:
ОбластьМакета = Макет.ПолучитьОбласть("Строка");
ОбластьМакета.Параметры.ДатаНачала = СтрокаТч.ДатаНачала;
// Устанавливаем формат отображения непосредственно для ячейки
ОбластьМакета.Область("R1C1").Формат = "ДФ=dd.MM.yyyy";
ТабДок.Вывести(ОбластьМакета);
В этом случае в самой таблице значений и в параметрах макета хранится точная дата, а пользователь видит красивое представление без лишних нулей времени.
Если вам необходимо производить сравнение дат в коде (например, проверять, относятся ли два события к одному дню) и вы хотите гарантировать, что время сброшено в 00:00:00, используйте быструю встроенную функцию НачалоДня(). Это гораздо надежнее и быстрее любых манипуляций со строками или описаниями типов.
Посмотрим на пример работы этой функции:
// Очищаем время для корректного сравнения
ДатаСравнения = НачалоДня(СтрокаТч.ДатаНачала);
Если ДатаСравнения = НачалоДня(ТекущаяДата()) Тогда
// Выполняем алгоритм, если даты совпадают без учета времени
КонецЕсли;
Если вы получаете данные для последующего анализа или выгрузки из базы данных с помощью механизма запросов, временную часть можно эффективно обнулить на уровне СУБД с помощью функции НАЧАЛОПЕРИОДА() с периодичностью ДЕНЬ.
Рассмотрим пример такого запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НАЧАЛОПЕРИОДА(Этапы.ДатаНачала, ДЕНЬ) КАК ДатаБезВремени,
| Этапы.Номер КАК Номер
|ИЗ
| Документ.ЭтапыПроизводства КАК Этапы";
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
// В колонке "ДатаБезВремени" таблицы значений будут даты со временем 00:00:00
Подведем итоги нашего разбора:
Дата в 1С принципиально не может существовать без времени. Нулевое время (00:00:00) — это естественная часть даты.НачалоДня(), а в запросах — функцию НАЧАЛОПЕРИОДА(..., ДЕНЬ).