Часто при разработке отчетов или построении диаграмм мы сталкиваемся с задачей: имеется дата со временем (например, 24.07.1995 23:27:10), и нам нужно получить из нее только дату (24.07.1995), при этом строго сохранив тип данных Дата. Преобразование в строку нас не устраивает, так как это нарушит сортировку и логику работы графиков. Разберем эту ситуацию по шагам и выясним причину такого поведения платформы, а также рассмотрим все возможные варианты решения.
Для начала проанализируем, как платформа работает с датами. В 1С:Предприятие 8 тип данных Дата физически хранит количество секунд, прошедших с 01.01.0001. На уровне платформы, памяти и базы данных невозможно получить значение этого типа совершенно без времени. При любых преобразованиях с сохранением типа Дата время никуда не удаляется, оно просто сбрасывается на начало суток (00:00:00).
Даже если в свойствах реквизита или измерения регистра вы выберете состав даты Дата, в базе данных все равно будет храниться значение с нулевым временем, а платформа лишь скроет его при визуальном отображении в интерфейсе.
Поэтому решение задачи всегда делится на два этапа: приведение даты к началу нужного периода (дня или часа) для группировки данных и скрытие времени при визуализации.
Если нам необходимо программно «отсечь» время (привести его к 00:00:00), мы используем встроенные функции платформы. Рассмотрим подробнее, как это сделать в коде 1С:
// Во встроенном языке используем функцию НачалоДня
ДатаБезВремени = НачалоДня(ИсходнаяДата);
Если мы получаем данные для отчета с помощью языка запросов, то для группировки записей по дням необходимо использовать функцию НАЧАЛОПЕРИОДА:
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(Таблица.Период, ДЕНЬ) КАК ПериодДень,
СУММА(Таблица.Сумма) КАК Сумма
ИЗ
РегистрНакопления.Продажи КАК Таблица
СГРУППИРОВАТЬ ПО
НАЧАЛОПЕРИОДА(Таблица.Период, ДЕНЬ)
Важный момент для построения диаграмм: если в какие-то дни не было движений, на графике образуются «провалы», и временная шкала нарушится. Чтобы этого избежать, в запросе следует использовать секцию ИТОГИ ПО с дополнением ПЕРИОДАМИ(ДЕНЬ, ДатаНачала, ДатаОкончания). Это позволит вывести даже пустые дни.
Если наша конечная цель — вывод данных в отчет или диаграмму с помощью СКД, преобразовывать дату в строку категорически нельзя. СКД отлично умеет работать с датами и сама правильно выстраивает хронологическую ось. Посмотрим на алгоритм действий:
Авто. В СКД автоматически появятся готовые поля ПериодДень и ПериодЧас.Период. Благодаря этому СКД поймет хронологию.ДФ=dd.MM.yyyy, а если нужна детализация до часов — ДФ='dd.MM.yyyy ЧЧ:ММ'.Если нам нужно строить диаграмму то по дням, то по часам в зависимости от выбранного периода, используем Условное оформление в настройках СКД. Задаем правило: если разница между началом и концом периода отчета меньше или равна дню, применяем формат с часами. В противном случае — формат только с днями. Данные при этом остаются типом Дата.
Разберем ситуацию, когда диаграмма формируется в табличном документе вручную средствами встроенного языка, без использования СКД. Нам нужно управлять отображением подписей, не ломая сортировку точек.
У шкалы объекта диаграммы есть свойство Формат. Если передать в него нужную форматную строку (например, ДЛФ=Д), ось автоматически скроет время, сохранив для значений точек правильный тип.
Также можно задать собственный текст для оси для каждой конкретной точки при обходе выборки. Выглядеть это будет примерно так:
Точка = Диаграмма.УстановитьТочку(Выборка.ПериодДень);
// Само значение остается датой для правильной сортировки на графике
Точка.Значение = Выборка.ПериодДень;
// А визуальное представление делаем строкой нужного формата
Точка.Текст = Формат(Выборка.ПериодДень, "ДФ=dd.MM.yyyy");
Таким образом, мы выяснили, что бороться с наличием времени в типе данных Дата бессмысленно — это базовая механика платформы. Правильный подход заключается в нормализации времени (сбросе на начало дня или часа) на этапе сбора данных и применении визуального форматирования на этапе их вывода пользователю.