Разработка и Конфигурация · 11 мин
Миллисекунды в 1С: точность времени и способы её измерения
Как работать с миллисекундами в 1С: ограничения типа Дата, способы замера времени выполнения кода, функции и обходные решения для точных измерений.
Вопрос «сколько в 1С миллисекунд» обычно возникает у разработчиков в двух ситуациях: когда нужно измерить время выполнения фрагмента кода с точностью до миллисекунд и когда требуется хранить метки времени точнее секунды. Здесь кроется важная особенность платформы: встроенный тип «Дата» в 1С имеет точность только до секунды, и миллисекунды в нём не хранятся и не отображаются.
Это ограничение не означает, что работать с миллисекундами невозможно. Платформа предоставляет несколько механизмов: функцию ТекущаяУниверсальнаяДатаВМиллисекундах(), замер производительности через технологический журнал, а также возможность хранить миллисекунды в числовых полях. Каждый способ имеет свои сценарии применения и ограничения.
Ниже разобраны практические приёмы: как замерить длительность операции, как зафиксировать точное время события, какие подводные камни возникают при сравнении дат и почему округление до секунд иногда ломает логику обмена данными.
Какая точность у типа «Дата» в 1С
Тип «Дата» во встроенном языке 1С содержит календарную дату и время суток, но минимальная единица хранения — одна секунда. Если вы присвоите переменной значение ТекущаяДата() и выведете его, то увидите формат вида «01.01.0001 0:00:00» без дробной части. Любые доли секунды отбрасываются платформой автоматически.
Это же ограничение действует для реквизитов объектов конфигурации с составом даты «Дата и время», для полей запросов и для регистров сведений с периодичностью «в пределах секунды». Даже максимальная периодичность регистра сведений не позволяет различить два события, произошедшие внутри одной секунды, — при записи двух записей с одинаковым периодом возникнет конфликт уникальности.
Практическое следствие: если бизнес-процесс требует различать события чаще одного раза в секунду (например, поток сообщений от оборудования или высокочастотный обмен), стандартного типа «Дата» недостаточно. Нужно либо хранить миллисекунды в отдельном числовом поле, либо проектировать регистрацию событий иначе — через последовательности, очереди или составные ключи.
Как замерить время выполнения кода в миллисекундах
Основной инструмент для точных замеров — функция ТекущаяУниверсальнаяДатаВМиллисекундах(). Она возвращает число типа «Число» — количество миллисекунд, прошедших с полуночи 1 января 0001 года по универсальному времени (UTC). Само по себе это число неудобно для чтения, но разность двух таких значений даёт точную длительность операции.
Типовой шаблон замера выглядит так: зафиксируйте значение функции до начала операции, выполните код, зафиксируйте значение после и вычислите разность. Результат — длительность в миллисекундах, которую можно вывести в сообщение, журнал регистрации или сохранить для анализа.
Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
// ... измеряемый код ...
Длительность = ТекущаяУниверсальнаяДатаВМиллисекундах() - Начало;
Сообщить("Выполнено за " + Длительность + " мс");Функция доступна начиная с версии платформы 8.3.6, в том числе на клиенте и на сервере. Возвращаемое значение — целое число, поэтому точность замера ограничена одной миллисекундой, чего достаточно для подавляющего большинства задач оптимизации.
- 1Перед измеряемым кодом сохраните значение ТекущаяУниверсальнаяДатаВМиллисекундах() в переменную
- 2Выполните целевой фрагмент кода или вызов процедуры
- 3Вычислите разность между новым и сохранённым значением
- 4Повторите замер 3–5 раз и сравните результаты — одиночный прогон искажается кэшированием
- 5Зафиксируйте медианное или минимальное значение как ориентир производительности
Почему ТекущаяДата() не подходит для точных замеров
Функция ТекущаяДата() возвращает значение типа «Дата» с точностью до секунды. Если операция занимает меньше секунды, разность двух таких значений будет равна нулю — вы не увидите реальной длительности. Для быстрых операций (запросы к СУБД, обработка небольших таблиц) это делает замер бесполезным.
Вторая проблема — часовые пояса. ТекущаяДата() на сервере возвращает время сервера, на клиенте — время клиентского компьютера, и они могут различаться. Функция ТекущаяУниверсальнаяДатаВМиллисекундах() всегда отсчитывает от UTC, поэтому разность значений корректна независимо от настроек пояса, пока оба замера выполняются в одном сеансе.
Хранение миллисекунд в базе данных
Если требуется сохранить метку времени с точностью до миллисекунд, стандартный реквизит типа «Дата» не подойдёт. Рабочее решение — добавить числовой реквизит достаточной разрядности и хранить в нём значение ТекущаяУниверсальнаяДатаВМиллисекундах(). Число это большое (порядка 15–16 знаков), поэтому длину числового поля нужно задавать с запасом — не менее 18 разрядов.
Альтернативный подход — хранить пару полей: стандартную дату (для отбора, периодических регистров и отчётов) и число миллисекунд внутри секунды (для точного упорядочивания). Такой вариант удобен, когда миллисекунды нужны только для сортировки событий внутри одной секунды, а основная логика работает с обычными датами.
При обмене данными с внешними системами (веб-сервисы, очереди сообщений, оборудование) миллисекунды часто приходят в формате Unix timestamp — числа миллисекунд с 1 января 1970 года. Для конвертации в дату 1С разделите значение на 1000, получите секунды и прибавьте их к дате начала эпохи Unix через стандартные операции с датами. Дробная часть после деления — это и есть миллисекунды, которые в тип «Дата» не поместятся.
Замер производительности: дополнительные инструменты
Ручные замеры через ТекущаяУниверсальнаяДатаВМиллисекундах() удобны для точечной проверки, но для системного анализа производительности платформа предлагает более мощные средства. Замер производительности в конфигураторе показывает длительность каждой строки кода и каждого вызова с детализацией до миллисекунд и долей миллисекунд, включая частоту вызовов.
Технологический журнал фиксирует события с точными временными метками: длительность запросов к СУБД, вызовов сервера, транзакций. Это основной инструмент диагностики «медленных» операций в рабочей базе, где нельзя вставлять отладочный код. Настройка выполняется через файл logcfg.xml, а события DBMSSQL, DBPOSTGRS, SDBL и CALL содержат поле длительности в микросекундах.
Для прикладного мониторинга в типовых конфигурациях есть подсистема оценки производительности из библиотеки стандартных подсистем: она автоматически собирает замеры ключевых операций и строит статистику. Если задача — контролировать время выполнения регламентных заданий или обменов, эта подсистема избавит от написания собственного механизма замеров.
Способы измерения времени
Точечные замеры в коде, логирование длительности операций. Ограничение: требует изменения кода
Анализ узких мест при разработке. Ограничение: только в отладочном сеансе, замедляет выполнение
Диагностика на рабочем сервере без изменения кода. Ограничение: требует настройки и разбора логов
Постоянный мониторинг ключевых операций. Ограничение: доступна в конфигурациях на БСП
Частые задачи и их решения
Пауза в выполнении кода
Встроенной функции задержки (аналога Sleep) во встроенном языке нет. Если нужна пауза — например, при опросе внешнего сервиса — используют цикл ожидания с проверкой ТекущаяУниверсальнаяДатаВМиллисекундах() или внешние компоненты. Учтите: активный цикл ожидания блокирует сеанс и нагружает процессор, поэтому для длительных пауз правильнее использовать фоновые задания с повторным запуском.
Уникальные метки для событий
Когда миллисекундной метки недостаточно для уникальности (несколько событий в одну миллисекунду), комбинируйте метку времени с уникальным идентификатором или порядковым номером. Это стандартный приём для журналов событий интеграций и очередей сообщений.
Вывод длительности в читаемом виде
Разность в миллисекундах удобно приводить к секундам делением на 1000 с округлением до нужного знака. Для длительных операций форматируйте результат в минуты и секунды — пользователю проще воспринимать «2 мин 15 с», чем «135000 мс».
Как проверить корректность замера
При 3–5 прогонах длительность отличается в пределах 10–20%
Значения скачут в разы — мешает кэш, фоновые процессы или сеть
Длительность соответствует ожиданиям от операции (запрос — миллисекунды, обмен — секунды)
Нулевое значение при явно долгой операции — вероятно, замер через ТекущаяДата()
Числовое поле вмещает 15–16 знаков без округления
Значения в базе обрезаны или хранятся в экспоненциальной форме
Ограничения и риски
Точность ТекущаяУниверсальнаяДатаВМиллисекундах() зависит от разрешения системного таймера операционной системы. На реальном оборудовании фактическая дискретность может составлять несколько миллисекунд, поэтому замеры короче 5–10 мс следует трактовать как приблизительные и усреднять по серии прогонов.
Не используйте миллисекундные метки как единственный критерий упорядочивания в распределённых системах. Часы разных серверов расходятся, и событие с более поздней меткой могло произойти раньше. Для строгого порядка применяйте серверные счётчики, номера сообщений или механизмы очередей.
Что важно запомнить
Тип «Дата» в 1С точен только до секунды. Миллисекунды доступны через ТекущаяУниверсальнаяДатаВМиллисекундах() — для замеров и хранения в числовых полях. Для системного анализа производительности используйте замер в конфигураторе и технологический журнал.
Частые вопросы
Можно ли вывести миллисекунды в формате даты, например «12:30:45.123»?
Стандартное форматирование даты такой дробной части не покажет, поскольку в типе «Дата» её нет. Решение — формировать строку вручную: отдельно выводить дату и отдельно число миллисекунд из числового значения, склеивая их строковой конкатенацией.
Работает ли ТекущаяУниверсальнаяДатаВМиллисекундах() в тонком и веб-клиенте?
Да, функция доступна на тонком клиенте, веб-клиенте, толстом клиенте и на сервере. Это делает её универсальным инструментом замеров в клиент-серверных сценариях.
Как перевести Unix timestamp в миллисекундах в дату 1С?
Разделите значение на 1000, чтобы получить секунды, затем прибавьте их к дате начала эпохи Unix (1 января 1970 года) стандартным сложением даты и числа секунд. Остаток от деления — миллисекунды, которые при необходимости сохраняйте отдельным числовым полем.
Почему два замера подряд одной операции дают разные значения?
На длительность влияют кэш СУБД и файловой системы, фоновые процессы сервера, сетевая задержка и сборка мусора платформы. Первый прогон обычно медленнее. Для достоверной оценки выполняйте серию замеров и ориентируйтесь на медиану или минимум.
Можно ли создать регистр сведений с периодичностью до миллисекунд?
Нет, максимальная периодичность регистра сведений — в пределах секунды. Если события происходят чаще, храните их в независимом регистре с числовым полем миллисекунд или используйте уникальные идентификаторы для различения записей.
Чем замерить длительность запроса к базе без изменения кода?
Включите технологический журнал с отбором событий СУБД (DBMSSQL, DBPOSTGRS и аналогичных) — в каждом событии фиксируется длительность выполнения. В конфигураторе аналогичную информацию показывает замер производительности с детализацией по строкам кода.