К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как в 1С получить только время из даты

Как в 1С получить только время из даты: функции Час, Минута, Секунда, Формат, запросы и типовые ошибки. Примеры кода для конфигуратора и запросов.

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

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

Как устроен тип «Дата» в 1С и почему времени отдельно нет

Тип «Дата» в 1С хранит момент времени с точностью до одной секунды: год, месяц, день, часы, минуты, секунды. Даже если вы указываете только календарную дату, время внутри значения равно 00:00:00. Именно поэтому «отрезать» время нельзя — можно только извлечь его составляющие или представить в нужном виде.

Это влияет и на проектирование конфигурации: если требуется хранить именно время (например, время начала смены), обычно выбирают один из трёх подходов — реквизит типа «Дата» с игнорируемой календарной частью, строковый реквизит формата «ЧЧ:ММ» или числовой реквизит (количество секунд от начала дня). Каждый вариант имеет ограничения, которые разобраны ниже.

Извлечение часов, минут и секунд функциями встроенного языка

Самый прямой способ — функции Час(), Минута() и Секунда(). Каждая принимает значение типа «Дата» и возвращает число: часы от 0 до 23, минуты и секунды от 0 до 59.

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

Ч = Час(ДатаДокумента); // например, 14

М = Минута(ДатаДокумента); // например, 5

С = Секунда(ДатаДокумента); // например, 30

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

ВремяСтрокой = Формат(Ч, "ЧЦ=2; ЧВН=") + ":"

+ Формат(М, "ЧЦ=2; ЧВН=") + ":"

+ Формат(С, "ЧЦ=2; ЧВН=");

// результат: "14:05:30"

Такой подход удобен, когда компоненты времени нужны по отдельности — например, для сравнения «событие произошло до 12:00» или для передачи часов и минут в разные поля внешней системы.

Получение времени строкой через функцию Формат()

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

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

ВремяКратко = Формат(ДатаДокумента, "ДЛФ=T"); // "14:05:30"

ВремяЧМ = Формат(ДатаДокумента, "ДФ=ЧЧ:мм"); // "14:05"

ВремяПолное = Формат(ДатаДокумента, "ДФ=ЧЧ:мм:сс"); // "14:05:30"

Разница между параметрами: ДЛФ=T выводит время в локальном формате (обычно ЧЧ:ММ:СС), а ДФ позволяет задать шаблон явно. В шаблоне ЧЧ — часы с ведущим нулём, мм — минуты, сс — секунды. Символы регистрозависимы: ММ в строке формата даты означает месяц, а мм — минуты, путать их нельзя.

Учтите, что результат Формат() — это строка. Сравнивать такие строки операторами «больше/меньше» можно только при фиксированной длине с ведущими нулями (ЧЧ:ММ:СС), иначе лексикографическое сравнение даст неверный результат.

Получение времени в запросах 1С

В языке запросов доступны одноимённые функции ЧАС(), МИНУТА() и СЕКУНДА(), которые применяются к полям типа «Дата»:

ВЫБРАТЬ

ЧАС(Регистрация.Период) КАК ЧасСобытия,

МИНУТА(Регистрация.Период) КАК МинутаСобытия

ИЗ

РегистрСведений.Регистрация КАК Регистрация

Типичный практический сценарий — выборка документов за определённый интервал времени внутри дня, например все продажи с 9:00 до 18:00 независимо от даты:

ВЫБРАТЬ

Продажи.Ссылка

ИЗ

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

ГДЕ

ЧАС(Продажи.Дата) >= 9

И ЧАС(Продажи.Дата) < 18

Здесь важно помнить о производительности: условие через функцию от поля не использует индекс по дате. На больших таблицах такой запрос приведёт к полному сканированию. Если выборки по времени выполняются регулярно, лучше хранить час или смещение от начала дня в отдельном индексированном реквизите и заполнять его при записи объекта.

Время как смещение от начала дня

Для сравнений и арифметики удобно представить время числом — количеством секунд, прошедших с начала дня. Получить его просто: вычесть из даты начало её же дня.

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

СекундОтНачалаДня = ДатаДокумента - НачалоДня(ДатаДокумента);

// число от 0 до 86399

Обратная операция — прибавить это число к любой дате, чтобы «перенести» время на другой день:

НоваяДата = НачалоДня(ДругаяДата) + СекундОтНачалаДня;

Этот приём незаменим, когда нужно сравнить два момента только по времени, игнорируя даты: достаточно сравнить два числа. Он же используется при хранении времени в числовом реквизите — один вариант проектирования, упомянутый выше.

Как хранить время в реквизитах: сравнение подходов

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

Способ храненияПлюсыОграничения
Дата (время с нулевой датой 01.01.0001)Стандартный ввод, форматирование, арифметика датЛегко случайно записать ненулевую дату; сортировка смешивается с датой
Число (секунды от начала дня)Простое сравнение, компактный индексНужна ручная конвертация для отображения; неочевидно для пользователя
Строка «ЧЧ:ММ»Наглядно, просто выгружатьНет валидации на уровне типа, ошибки сравнения, ручной контроль формата

Что выбрать для хранения времени

Реквизит типа «Дата»

Подходит, когда время — часть полноценного момента (дата и время документа). Для «чистого» времени требует дисциплины: всегда обнулять дату через НачалоДня().

Число секунд от начала дня

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

Строка ЧЧ:ММ

Допустимо для простых справочников без вычислений. Для любой логики сравнения — худший вариант из-за отсутствия типизации.

Если используется реквизит типа «Дата» для хранения только времени, при записи принудительно обнуляйте календарную часть: Объект.ВремяНачала = НачалоДня(Объект.ВремяНачала) + СекундОтНачалаДня. Иначе в данных появятся разные даты, и сравнение значений сломается.

Типичные ошибки и их диагностика

Типичные ошибки
01
Использование «ДФ=ЧЧ:ММ» — вместо минут выводится месяц; проверяйте регистр букв в форматной строке.
02
Сравнение строк времени без ведущих нулей: «9:05» окажется «больше» «14:00»; используйте формат ЧЧ:ММ:СС или числовое сравнение.
03
Забытое обнуление даты в реквизите «только время» — сравнение значений с разными датами даёт неверный результат.
04
Условие ЧАС(Поле) в запросе по большой таблице без отдельного индексированного реквизита — резкое падение производительности.
05
Использование ТекущаяДата() вместо ТекущаяДатаСеанса() на сервере — время клиента и сервера могут различаться по часовому поясу.

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

Контрольные точки

Как проверить результат

Строка времени после Формат()
Норма

Часы и минуты совпадают с исходной датой, минуты не равны номеру месяца

Тревожный признак

В позиции минут стоит номер месяца — ошибка в регистре букв формата

Сравнение двух значений «только время»
Норма

Результат сравнения не зависит от календарной части

Тревожный признак

Порядок меняется при смене даты — даты не обнулены

Запрос с условием по ЧАС()
Норма

Выполняется быстро на рабочем объёме данных

Тревожный признак

Заметная задержка — условие не использует индекс, нужен отдельный реквизит

Краткий алгоритм выбора способа

Маршрут решения

Как выбрать способ

Нужно показать время пользователю или выгрузить в файлИспользуйте Формат(Дата, "ДФ=ЧЧ:мм:сс") или ДЛФ=T
Нужны часы, минуты, секунды как числа для логикиПримените Час(), Минута(), Секунда() в коде или запросе
Нужно сравнивать или складывать времяПереведите в секунды от начала дня: Дата - НачалоДня(Дата)
Время фильтруется в запросах по большой таблицеДобавьте числовой реквизит с часом или секундами и индексируйте его
Итог

Что важно запомнить

В 1С нет отдельного типа «время»: используйте Час/Минута/Секунда для компонентов, Формат с ДФ=ЧЧ:мм:сс для строки, разность с НачалоДня() для арифметики. Следите за регистром букв в формате, обнулением даты и производительностью запросов с функциями.

Частые вопросы

Можно ли создать реквизит типа «время без даты» в конфигураторе?

Нет, такого типа в платформе не существует. Ближайший вариант — реквизит типа «Дата» с составом даты «Время»: в свойствах реквизита можно указать, что хранится только время. При этом физически дата остаётся равной 01.01.0001, а платформа сама ограничивает ввод и отображение временной частью. Это предпочтительный способ для реквизитов вроде «Время начала смены».

Как вывести время в формате 12 часов с AM/PM?

Стандартных символов AM/PM в форматной строке ДФ нет. Нужно вручную вычислить: взять Час(Дата), при необходимости вычесть 12, и добавить суффикс «AM» или «PM» в зависимости от значения часа. Обычно проще согласовать с пользователями 24-часовой формат.

Почему Формат(Дата, "ДФ=ЧЧ:мм") возвращает неправильные минуты?

Скорее всего, в форматной строке написаны прописные «ММ» — это месяц, а не минуты. Проверьте регистр: часы — «ЧЧ», минуты — строчные «мм», секунды — строчные «сс». Также убедитесь, что функция Формат вызывается в контексте, где доступна (на тонком клиенте она работает, но локальные форматы могут отличаться).

Как сравнить два документа только по времени, игнорируя дату?

Переведите оба значения в секунды от начала дня: Дата1 - НачалоДня(Дата1) и Дата2 - НачалоДня(Дата2), затем сравните полученные числа. Сравнивать напрямую значения типа «Дата» нельзя — в них участвует и календарная часть.

Как получить время из даты в СКД или динамическом списке?

В тексте запроса используйте функции ЧАС(), МИНУТА(), СЕКУНДА() — они доступны в выражениях СКД так же, как в обычных запросах. Для отображения строкой добавьте вычисляемое поле и формируйте строку в коде при выводе, либо используйте формат поля в настройках компоновки.

Влияет ли часовой пояс на извлекаемое время?

Да. Функции Час(), Минута(), Секунда() возвращают компоненты того значения даты, которое им передано. Если значение записано в одном поясе, а читается в сеансе с другим поясом, отображаемое время может различаться. Для единообразия используйте ТекущаяДатаСеанса() и при необходимости явно храните часовой пояс данных.