Работа с датами и временем в 1С:Предприятие — одна из самых востребованных задач при разработке отчетов, обработок и конфигураций. Часто требуется получить только временную часть из полной даты (например, 15.07.2026 14:30:45 → 14:30:45), но не все знают, как это сделать корректно. В этой статье мы разберем 5 рабочих способов извлечения времени, включая нюансы для разных версий платформы (8.2, 8.3) и типов данных.
Проблема усложняется тем, что в 1С нет отдельного типа данных "время" — временные значения хранятся как часть типа Дата. Это означает, что для выделения времени потребуются специальные функции или преобразования. Мы рассмотрим как стандартные методы (Формат(), НачалоДня()), так и менее очевидные приемы с использованием Тип() и строковых операций. Особое внимание уделим производительности и совместимости решений.
1. Способ: функция Формат() — простейшее решение для вывода
Самый очевидный и универсальный метод — использование функции Формат(). Она позволяет преобразовать дату в строку с заданным форматом, оставив только временную часть. Этот способ подходит, когда вам нужно отобразить время пользователю или записать его в строку.
Основные плюсы метода:
- 🔹 Простота — одна строка кода
- 🔹 Гибкость форматирования (можно вывести только часы, часы:минуты и т.д.)
- 🔹 Работает во всех версиях 1С 8.x
Пример кода для вывода времени в формате ЧЧ:ММ:СС:
ТекущаяДата = ТекущаяДата();
ТолькоВремя = Формат(ТекущаяДата, "ЧЧ:ММ:СС");
// Результат: "14:30:45" (если текущее время 14:30:45)
Если вам нужно время без секунд, используйте формат "ЧЧ:ММ". Для вывода с миллисекундами подойдет "ЧЧ:ММ:СС.ммм". Обратите внимание, что результат — это строка, а не дата. Для дальнейших расчетов потребуется преобразование обратно в тип Дата.
Используйте функцию Формат() с параметром "ДЛФ=Истина", чтобы получить время в формате текущей локали пользователя: Формат(ТекущаяДата(), "ЧЧ:ММ:СС", "ДЛФ=Истина")
2. Способ: арифметика с датами (НачалоДня() и секунды)
Более "математический" подход основан на том, что в 1С даты хранятся как количество секунд с начала отсчета (1 января 0001 года). Мы можем вычесть из исходной даты начало текущего дня и получить временной интервал, который затем преобразуем в строку.
Алгоритм действий:
- Получаем начало текущего дня функцией
НачалоДня() - Вычитаем его из исходной даты — получаем количество секунд с начала дня
- Форматируем результат как время
Пример кода:
ТекущаяДата = ТекущаяДата();
СекундыСНачалаДня = ТекущаяДата - НачалоДня(ТекущаяДата);
ТолькоВремя = Формат(СекундыСНачалаДня, "ЧЧ:ММ:СС");
// Альтернативный вариант с созданием новой даты:
ТолькоВремяДата = НачалоДня(ТекущаяДата) + СекундыСНачалаДня;
Этот метод возвращает значение типа Дата (во втором варианте), которое можно использовать в дальнейших расчетах. Однако он требует больше операций, чем Формат(), поэтому менее производителен для массовых операций. Зато позволяет работать с временными интервалами напрямую.
3. Способ: строковые операции (Для опытных)
Если вам нужно не просто отобразить время, а разобрать его на компоненты (часы, минуты, секунды отдельно), можно использовать строковые функции. Этот метод требует больше кода, но дает максимальную гибкость.
Последовательность действий:
- 🔹 Преобразуем дату в строку с нужным форматом
- 🔹 Извлекаем подстроки с часами, минутами, секундами
- 🔹 При необходимости преобразуем строки в числа
Пример кода для разбора времени:
ТекущаяДата = ТекущаяДата();
СтрокаВремени = Формат(ТекущаяДата, "ЧЧ:ММ:СС");
// Разбиваем строку по символу ":"
МассивВремени = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(СтрокаВремени, ":");
Часы = Число(МассивВремени[0]);
Минуты = Число(МассивВремени[1]);
Секунды = Число(МассивВремени[2]);
// Теперь можно работать с компонентами отдельно
Если Часы > 12 Тогда
Сообщить("Сейчас второй половины дня");
КонецЕсли;
Этот способ полезен, когда нужно:
- 🔸 Сравнивать отдельные компоненты времени (например, только часы)
- 🔸 Выполнять арифметические операции с частями времени
- 🔸 Форматировать время нестандартным образом
Опасность строковых операций
При преобразовании даты в строку и обратно возможны ошибки, если формат времени не соответствует ожидаемому (например, в разных локалях разделителем может быть не ":" а другой символ). Всегда проверяйте результат на корректность!
4. Способ: функция Тип() и конструктор Дата()
Малоизвестный, но эффективный метод — использование функции Тип() для создания новой даты с нулевой датой и нужным временем. Этот подход возвращает полноценный объект типа Дата, с которым можно работать дальше.
Преимущества метода:
- 🔹 Возвращает тип Дата, а не строку
- 🔹 Позволяет выполнять временные расчеты
- 🔹 Совместим с 1С 8.2 и 8.3
Пример кода:
ТекущаяДата = ТекущаяДата();
// Создаем новую дату с текущим временем, но датой 01.01.0001
ТолькоВремя = Дата(1, 1, 1,
ТекущаяДата.Час(),
ТекущаяДата.Минута(),
ТекущаяДата.Секунда());
// Теперь ТолькоВремя содержит только временную часть
// Например: 01.01.0001 14:30:45
Обратите внимание, что в результате мы получаем дату 01.01.0001 с нужным временем. Это может вызвать проблемы при сравнении с другими датами. Чтобы избежать путаницы, всегда явно указывайте, что работаете с временной частью:
Если ТолькоВремя.Дата() = Дата(1,1,1) Тогда
// Это время без даты
КонецЕсли;
Функция Тип() в сочетании с конструктором Дата() — единственный способ получить временную часть в виде объекта типа Дата, пригодного для дальнейших расчетов.
5. Способ: пользовательские функции (Для повторного использования)
Если вам часто приходится извлекать время из даты, имеет смысл создать собственную функцию и поместить ее в общий модуль. Это упростит поддержку кода и сделает его более читаемым.
Пример универсальной функции:
Функция ПолучитьВремяИзДаты(Знач ДатаВремя, ФорматВывода = "ЧЧ:ММ:СС") Экспорт
// Вариант 1: возвращаем строку
Если ФорматВывода <> Неопределено Тогда
Возврат Формат(ДатаВремя, ФорматВывода);
// Вариант 2: возвращаем дату с нулевой датой
Иначе
Возврат Дата(1, 1, 1,
ДатаВремя.Час(),
ДатаВремя.Минута(),
ДатаВремя.Секунда());
КонецЕсли;
КонецФункции
Преимущества такого подхода:
- 🔹 Единообразие кода по всему проекту
- 🔹 Легко изменить логику в одном месте
- 🔹 Можно добавить обработку ошибок и валидацию
Пример использования:
ТекущееВремяСтрока = ПолучитьВремяИзДаты(ТекущаяДата(), "ЧЧ:ММ");
ТекущееВремяДата = ПолучитьВремяИзДаты(ТекущаяДата());
Функция корректно обрабатывает неопределенные значения|Функция работает с разными форматами времени|Функция возвращает ожидаемый тип данных (строка или дата)|Добавлены комментарии для поддержки кода-->
Сравнение методов: какой выбрать?
Выбор оптимального способа зависит от вашей задачи. В таблице ниже приведено сравнение всех рассмотренных методов:
| Метод | Возвращаемый тип | Производительность | Гибкость | Сложность | Когда использовать |
|---|---|---|---|---|---|
Формат() |
Строка | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ | Для отображения времени пользователю |
Арифметика с НачалоДня() |
Дата или число | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | Для расчетов с временными интервалами |
| Строковые операции | Строка/число | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | Для разбора времени на компоненты |
Тип() + Дата() |
Дата | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | Для работы с временем как с объектом Дата |
| Пользовательская функция | Зависит от реализации | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐ | Для повторного использования в проекте |
Для большинства задач оптимальным решением будет Формат() — он прост, быстр и покрывает 80% случаев. Если вам нужно работать с временем как с объектом (например, складывать временные интервалы), лучше использовать метод с НачалоДня() или Тип().
При работе с большими массивами данных (например, в отчетах) отдайте предпочтение методу Формат() — он показывает лучшую производительность при массовых операциях.
Типичные ошибки и как их избежать
При извлечении времени из даты разработчики часто сталкиваются с типичными проблемами. Вот наиболее распространенные ошибки и способы их решения:
1. Путаница с типами данных
Многие функции возвращают строку, а не дату. Если вы пытаетесь выполнить арифметические операции со строкой (например, прибавить 30 минут), получите ошибку.
// ОШИБКА: нельзя прибавлять число к строке
ВремяСтрока = Формат(ТекущаяДата(), "ЧЧ:ММ");
НовоеВремя = ВремяСтрока + 30; // Ошибка!
Решение: Преобразуйте строку обратно в дату или работайте с числом секунд.
2. Проблемы с локализацией
Формат времени может отличаться в разных языковых настройках (например, в некоторых локалях используется 12-часовой формат с AM/PM).
// Может вернуть "02:30:45 PM" вместо "14:30:45"
Формат(ТекущаяДата(), "ЧЧ:ММ:СС", "ЛН=EN");
Решение: Явно указывайте формат с параметром "ДЛФ=Ложь" для игнорирования локали.
3. Потеря точности при операциях
При арифметических операциях с датами (вычитание НачалоДня()) можно потерять миллисекунды, если не учитывать их явно.
Решение: Используйте функцию ДатаВремяВСекундах() для точных расчетов:
СекундыСМиллисекундами = ДатаВремяВСекундах(ТекущаяДата()) - ДатаВремяВСекундах(НачалоДня(ТекущаяДата()));
Всегда проверяйте результат извлечения времени на крайних значениях: начало дня (00:00:00), конец дня (23:59:59), переход через полночь. Это поможет избежать скрытых ошибок.
4. Ошибки при сравнении временных значений
Если вы создали дату с нулевой датой (01.01.0001), ее сравнение с обычными датами может давать неожиданные результаты.
Дата1 = Дата(1,1,1,14,0,0); // 01.01.0001 14:00:00
Дата2 = Дата(10,7,2026,10,0,0); // 10.07.2026 10:00:00
// Дата1 > Дата2 вернет Истина, хотя по времени 14:00 > 10:00
Решение: Для сравнения только временной части извлекайте часы, минуты и секунды отдельно.
Как сравнить только время без учета даты?
Используйте выражение:
(Дата1 - НачалоДня(Дата1)) > (Дата2 - НачалоДня(Дата2))
Это сравнит только количество секунд с начала дня.
Практические примеры использования
Рассмотрим реальные сценарии, где требуется извлечение времени из даты в 1С:
1. Отчет по времени выполнения задач
Допустим, у вас есть журнал задач с полями ДатаНачала и ДатаОкончания. Вам нужно показать в отчете только время выполнения (без даты).
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Формат(ЖурналЗадач.ДатаНачала, ""ЧЧ:ММ"") КАК ВремяНачала,
| Формат(ЖурналЗадач.ДатаОкончания, ""ЧЧ:ММ"") КАК ВремяОкончания
|ИЗ
| Документ.ЖурналЗадач КАК ЖурналЗадач";
Результат = Запрос.Выполнить();
2. Проверка рабочего времени
Вам нужно проверить, попадает ли время создания документа в рабочие часы (с 9:00 до 18:00).
Функция ВРабочееВремя(ДатаСоздания)
Час = ДатаСоздания.Час();
Возврат Час >= 9 И Час < 18;
КонецФункции
3. Группировка данных по часам
При построении отчета по продажам вам нужно сгруппировать данные по часам дня.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Формат(Документ.Продажи.Дата, ""ЧЧ"") КАК ЧасДня,
| СУММА(Документ.Продажи.Сумма) КАК СуммаПродаж
|ИЗ
| Документ.Продажи КАК Документ.Продажи
|ГРУППИРОВАТЬ ПО
| Формат(Документ.Продажи.Дата, ""ЧЧ"")";
Результат = Запрос.Выполнить();
4. Расчет продолжительности в часах:минутах
Вам нужно показать продолжительность события в удобном формате.
Функция ПродолжительностьВЧЧММ(ДатаНачала, ДатаОкончания)
Секунды = ДатаОкончания - ДатаНачала;
Часы = Цел(Секунды / 3600);
Минуты = Цел((Секунды % 3600) / 60);
Возврат Формат(Часы, "Ч=0") + ":" + Формат(Минуты, "Ч=00");
КонецФункции
Эти примеры демонстрируют, как извлечение времени применяется в реальных бизнес-задачах. Главное — выбирать метод, который лучше всего подходит для конкретной ситуации.
FAQ: Частые вопросы по работе со временем в 1С
Можно ли в 1С создать переменную только с временем без даты?
Нет, в 1С нет отдельного типа данных "время". Временные значения всегда хранятся как часть типа Дата. Однако вы можете создать дату с минимальной датой (01.01.0001) и нужным временем, как показано в способе с функцией Тип().
Как прибавить 30 минут к временной части даты?
Лучше всего использовать арифметические операции с секундами:
НоваяДата = ИсходнаяДата + 30 * 60; // 30 минут = 1800 секунд
Если вам нужно прибавить время только к временной части (не затрагивая дату), используйте:
НоваяДата = НачалоДня(ИсходнаяДата) + (ИсходнаяДата - НачалоДня(ИсходнаяДата)) + 1800;
Почему при форматировании времени получаю неверный час (например, 14 вместо 2 PM)?
Это происходит из-за настроек локали. В некоторых языковых стандартах (например, английском) используется 12-часовой формат с обозначениями AM/PM. Чтобы получить 24-часовой формат, используйте:
Формат(ТекущаяДата(), "ЧЧ:ММ:СС", "ДЛФ=Ложь")
Параметр "ДЛФ=Ложь" отключает зависимость от локали.
Как извлечь время из поля типа "Дата" в запросе 1С?
В языке запросов 1С можно использовать функцию ФОРМАТ() или арифметические операции. Примеры:
ВЫБРАТЬ
ФОРМАТ(Документ.Событие.Дата, "ЧЧ:ММ:СС") КАК ВремяСобытия
ИЗ
Документ.Событие КАК Документ.Событие
-- Или через секунды с начала дня:
ВЫБРАТЬ
(Документ.Событие.Дата - НАЧАЛОДНЯ(Документ.Событие.Дата)) КАК СекундыСНачалаДня
ИЗ
Документ.Событие КАК Документ.Событие
Можно ли сравнивать временные значения напрямую?
Да, но с оговорками. Если у вас две даты с одинаковой датой (01.01.0001), их можно сравнивать напрямую. В противном случае сравниваются сначала даты, а потом время. Для сравнения только временной части используйте:
Если (Дата1 - НачалоДня(Дата1)) > (Дата2 - НачалоДня(Дата2)) Тогда
// Время в Дата1 позже, чем в Дата2
КонецЕсли;