Получает текущую универсальную дату в миллисекундах (в UTC, начиная с 01.01.0001 00:00:00).
Синтаксис
ТекущаяУниверсальнаяДатаВМиллисекундах()Полное описание, параметры и ограничения
Глобальный контекст.ТекущаяУниверсальнаяДатаВМиллисекундах (Global context.CurrentUniversalDateInMilliseconds)
Глобальный контекст (Global context)
ТекущаяУниверсальнаяДатаВМиллисекундах (CurrentUniversalDateInMilliseconds)
Доступен, начиная с версии 8.2.
Синтаксис:
ТекущаяУниверсальнаяДатаВМиллисекундах()
Возвращаемое значение:
Тип: Число.
Описание:
Получает текущую универсальную дату в миллисекундах (в UTC, начиная с 01.01.0001 00:00:00).
Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер, интеграция.
Использование в версии:
Доступен, начиная с версии 8.2.
Методическая информация
Практические примеры
Не перепутать миллисекунды 1С с timestamp внешнего API
Восстанавливаем UTC из счётчика 1С и сравниваем его с текущей датой UTC. Отдельно показываем дату сеанса, чтобы не выдавать её за универсальный момент.
Где и как запускать
Полный серверный общий модуль учебной копии. Только чтение настроек и вычисления в памяти.
Подготовка
Работайте в отдельной учебной копии базы. Создайте серверный общий модуль УчебныеЗадачи, вставьте полный модуль урока и вызовите ВыполнитьПример() из серверного обработчика учебной команды.
Код выполняется на сервере: часть функций локализации и часовых поясов недоступна непосредственно в тонком клиенте. Реквизиты пользователя, региональные настройки и часовые пояса код не меняет.
Для двух уроков о метаданных используйте копию КА2 Progress: в исходном Languages/Русский.xml действительно есть язык Русский с КодЯзыка = ru. Остальные уроки не требуют объектов конкретной конфигурации.
Процедура ВыполнитьПример() Экспорт
UTCДо = ТекущаяУниверсальнаяДата();
Миллисекунды1С = ТекущаяУниверсальнаяДатаВМиллисекундах();
UTCПосле = ТекущаяУниверсальнаяДата();
ВосстановленноеUTC = Дата(1, 1, 1) + Цел(Миллисекунды1С / 1000);
Сообщить(ТипЗнч(Миллисекунды1С) = Тип("Число"));
Сообщить(ТипЗнч(ВосстановленноеUTC) = Тип("Дата"));
Если UTCПосле >= UTCДо Тогда
Сообщить(ВосстановленноеUTC >= UTCДо И ВосстановленноеUTC <= UTCПосле);
Иначе
Сообщить("Системные часы изменились между вызовами; интервальную проверку пропускаем");
КонецЕсли;
Сообщить("Восстановленное UTC: " + Формат(ВосстановленноеUTC, "ДФ=yyyy-MM-dd HH:mm:ss"));
ДатаСеанса = ТекущаяДатаСеанса();
Сообщить("Дата сеанса: " + Формат(ДатаСеанса, "ДФ=yyyy-MM-dd HH:mm:ss"));
Сообщить("Пояс сеанса: " + ЧасовойПоясСеанса());
УчебныйUTC = Дата(1970, 1, 1, 0, 0, 10);
УчебныеМиллисекундыUnix = (УчебныйUTC - Дата(1970, 1, 1)) * 1000;
Сообщить(УчебныеМиллисекундыUnix = 10000);
КонецПроцедурыРазбор по шагам
ТекущаяУниверсальнаяДатаВМиллисекундах считает миллисекунды с 01.01.0001. Делим на 1000 и берём целую часть, потому что обычная Дата имеет секундную точность.
Дата(1, 1, 1) — начало шкалы счётчика 1С. Прибавление количества секунд восстанавливает UTC, а не местное время сервера.
Два независимых чтения UTC ограничивают момент измерения. Обычно интервальная проверка истинна; системная корректировка часов может повлиять на диагностику. Это не монотонный таймер.
ТекущаяДатаСеанса возвращает дату сервера в поясе сеанса; приоритет — пояс сеанса, затем базы, затем сервера. Это не второй способ получить UTC.
Unix-миллисекунды имеют начало 01.01.1970. Последний расчёт только для своего явно заданного UTC: 10 секунд после начала дают 10000. Контракт реального внешнего API необходимо проверить отдельно.
Как проверить результат
Две проверки типов — Истина. При неизменных часах интервальная проверка — Истина; учебный Unix-пример в конце — Истина.
Значения текущего времени меняются при каждом запуске. Не сравнивайте их с жёстко заданной сегодняшней датой.
В коде нет setter часового пояса, изменения системных часов или обращения к внешнему API.
Ожидаемый результат
Начинающий различает UTC, дату сеанса и две разные эпохи миллисекунд.
На что обратить внимание
Нельзя передавать счётчик миллисекунд 1С в API, ожидающий Unix timestamp, без преобразования эпохи.
Не оценивайте точную производительность по настенным часам: они могут корректироваться ОС.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
ВызватьПаузу: измерить короткую паузу в собственном фоновом задании
Кнопка обычной формы запускает собственную серверную процедуру как фоновое задание. Процедура делает паузу 1500 миллисекунд между двумя настоящими отсчетами UTC, отправляет одно сообщение с измерением; форма проверяет паспорт и успешное завершение задания, затем показывает именно полученный текст.
Где и как запускать
Сервер: собственный неглобальный общий модуль, исполнение только штатным фоновым заданием. Запуск и ожидание — собственная обычная форма толстого управляемого клиента 8.5.1.1343.
Подготовка
Это будущий опыт только в НОВОЙ пустой файловой базе на своей отдельной Windows VM. Сейчас 1С и задания не запускались. Создайте базу C:\1c-study\OwnedPause85_bf8a7d85\IB, не используйте рабочую конфигурацию и внешнее COM-соединение. В списке баз явно зарегистрируйте эту папку: код принимает только строку File="C:\1c-study\OwnedPause85_bf8a7d85\IB";. Другой формат — остановка до запуска, а не разрешение подменить путь.
Имя новой конфигурации = УчебнаяФоноваяПауза85, Версия = bf8a7d85-ff04-46ab-9b58-6493e742adcc. Платформа = 8.5.1.1343, русский встроенный язык, Основной режим запуска = Управляемое приложение, интерфейс Такси, Использовать обычные формы в управляемом приложении = Истина, совместимость = НеИспользовать. Это маркеры подготовки, а не доказательство владения. Если редактор скрывает обычные формы, Сервис → Параметры → Общие: выберите вид редактирования для обычного приложения; это видимость редактора, не изменение основного режима запуска конфигурации.
Один собственный учебный пользователь, одно клиентское подключение, никаких регламентных заданий, расширений, подписок, других модулей и производственных данных. Для этого отдельного стенда вручную создайте свою учебную роль с полными правами и назначьте ее своему пользователю; это не обещание минимальных прав для рабочей базы. До опыта владелец отдельно обеспечивает лицензию 1С и доступность выполнения фоновых заданий.
Общие → Общие модули: создайте только УчебнаяПауза85. Глобальный = Нет, Сервер = Да, Клиент (обычное приложение) = Нет, Клиент (управляемое приложение) = Нет, Внешнее соединение = Нет, Вызов сервера = Нет, Привилегированный = Нет, Повторное использование возвращаемых значений = НеИспользовать. Основной код карточки вставьте ЦЕЛИКОМ в этот модуль. Измерить85 экспортирована для штатного запуска менеджером, а не прямого вызова с клиента.
Общие → Общие формы: создайте только обычную форму Пауза85, не управляемую. В ее реквизитах задайте Согласие85 / Булево, Остановка85 / Булево и Результат85 / Строка неограниченной длины. Начальные значения в редакторе не требуются: фактическая Остановка85 на новом экземпляре должна быть Ложь, код не сбрасывает ее. Пользователь сам отмечает Согласие85.
На вкладке Диалог добавьте флажок для Согласие85 и многострочное поле Результат85 только для просмотра, связав их с одноименными реквизитами. Остановка85 в диалог не выводится. Добавьте обычную кнопку Запустить85: ее штатное событие Нажатие свяжите с Запустить85 без параметров. Это Кнопка.Нажатие(), не команда управляемой формы с параметром Команда. В модуль формы вставьте целиком отдельный блок Пауза85 ниже.
Конфигурация → Открыть модуль управляемого приложения: вставьте отдельный блок УправляемоеПриложение ниже. Штатный ПриНачалеРаботыСистемы() получает собственную именованную форму с настоящим новым ключом уникальности и открывает ее. Обработчики вручную не вызывайте.
В будущем проверьте конфигурацию, обновите только свою учебную базу и запустите толстый клиент в управляемом режиме. До нажатия прочитайте ограничения: одна попытка создаст настоящее фоновое задание; платформа может хранить историю и сообщения. Ожидание в форме может на время остановить отзывчивость ее интерфейса. Затем явно отметьте согласие и один раз нажмите Запустить85.
Согласие тратится и Остановка85 устанавливается ДО создания ключа и запуска. Ни успешное завершение, ни ошибка не разрешают повтор в этой форме. При ошибке или истечении ожидания задание может оставаться активным; код его не отменяет, не опрашивает, не запускает повторно и не чистит историю. STOP не означает отмену или откат.
Процедура Измерить85(Интервал, Ключ) Экспорт
#Если Сервер Тогда
Система = Новый СистемнаяИнформация;
Если ТипЗнч(Система) <> Тип("СистемнаяИнформация") Тогда
ВызватьИсключение "Нужна платформа 8.5.1.1343";
КонецЕсли;
Если ТипЗнч(Интервал) <> Тип("Число") Или Интервал <> 1500
Или ТипЗнч(Ключ) <> Тип("Строка") Или Ключ = "" Тогда
ВызватьИсключение "Нужны свой ключ и учебный интервал 1500 мс";
КонецЕсли;
Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
Если ТипЗнч(Начало) <> Тип("Число") Тогда
ВызватьИсключение "Не получен числовой отсчет UTC";
КонецЕсли;
ВызватьПаузу(Интервал);
Конец = ТекущаяУниверсальнаяДатаВМиллисекундах();
Если ТипЗнч(Конец) <> Тип("Число") Тогда
ВызватьИсключение "Не получен второй числовой отсчет UTC";
КонецЕсли;
Разность = Конец - Начало;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Пауза85|" + Ключ + "|интервал, мс: " + Строка(Интервал)
+ "; UTC до: " + Строка(Начало) + "; UTC после: " + Строка(Конец)
+ "; разность, мс: " + Строка(Разность);
Если Разность < 0 Тогда
Сообщение.Текст = Сообщение.Текст + "; часы сместились назад: это не ошибка паузы";
КонецЕсли;
Сообщение.Сообщить();
#Иначе
ВызватьИсключение "Этот модуль предназначен только для своего фонового задания";
#КонецЕсли
КонецПроцедуры
Настоящая кнопка обычной формы: один запуск, ограниченное ожидание и полученный текст
Общие → Общие формы → Пауза85 → Модуль
Толстый управляемый клиент, собственная обычная Форма
Процедура Запустить85()
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Попытка
Если ТипЗнч(Остановка85) <> Тип("Булево") Или Остановка85 <> Ложь
Или ТипЗнч(Согласие85) <> Тип("Булево") Или Согласие85 <> Истина
Или ТипЗнч(Результат85) <> Тип("Строка") Или ТипЗнч(ЭтаФорма) <> Тип("Форма") Тогда
ВызватьИсключение "Нужны своя новая обычная форма и явно отмеченное согласие";
КонецЕсли;
Система = Новый СистемнаяИнформация;
Соединение = СтрокаСоединенияИнформационнойБазы();
Если ТипЗнч(Система) <> Тип("СистемнаяИнформация") Или ТипЗнч(Соединение) <> Тип("Строка") Или Соединение <> "File=""C:\1c-study\OwnedPause85_bf8a7d85\IB"";" Тогда
ВызватьИсключение "Не своя новая файловая база на платформе 8.5.1.1343";
КонецЕсли;
Если Метаданные.ИспользоватьОбычныеФормыВУправляемомПриложении <> Истина Тогда
ВызватьИсключение "Не своя точная подготовка конфигурации";
КонецЕсли;
Согласие85 = Ложь;
Остановка85 = Истина;
Результат85 = "Попытка потрачена. Успешный результат еще не получен.";
ИдентификаторКлюча = Новый УникальныйИдентификатор();
Если ТипЗнч(ИдентификаторКлюча) <> Тип("УникальныйИдентификатор") Тогда
ВызватьИсключение "Не получен настоящий новый идентификатор";
КонецЕсли;
Ключ = Строка(ИдентификаторКлюча);
Параметры = Новый Массив;
Параметры.Добавить(1500);
Параметры.Добавить(Ключ);
Менеджер = ФоновыеЗадания;
Если ТипЗнч(Менеджер) <> Тип("МенеджерФоновыхЗаданий") Тогда
ВызватьИсключение "Не получен штатный менеджер заданий";
КонецЕсли;
Задание = Менеджер.Выполнить("УчебнаяПауза85.Измерить85", Параметры, Ключ, "Собственная учебная пауза 1500 мс");
Если ТипЗнч(Задание) <> Тип("ФоновоеЗадание") Тогда
ВызватьИсключение "Не получено собственное фоновое задание";
КонецЕсли;
Идентификатор = Задание.УникальныйИдентификатор;
Если ТипЗнч(Идентификатор) <> Тип("УникальныйИдентификатор")
Или ТипЗнч(Задание.Ключ) <> Тип("Строка") Или Задание.Ключ <> Ключ
Или ТипЗнч(Задание.ИмяМетода) <> Тип("Строка") Или Задание.ИмяМетода <> "УчебнаяПауза85.Измерить85" Тогда
ВызватьИсключение "Паспорт запущенного задания не совпал";
КонецЕсли;
Обновленное = Задание.ОжидатьЗавершенияВыполнения(10);
Если ТипЗнч(Обновленное) <> Тип("ФоновоеЗадание")
Или ТипЗнч(Обновленное.УникальныйИдентификатор) <> Тип("УникальныйИдентификатор")
Или Обновленное.УникальныйИдентификатор <> Идентификатор
Или ТипЗнч(Обновленное.Ключ) <> Тип("Строка") Или Обновленное.Ключ <> Ключ
Или ТипЗнч(Обновленное.ИмяМетода) <> Тип("Строка")
Или Обновленное.ИмяМетода <> "УчебнаяПауза85.Измерить85"
Или ТипЗнч(Обновленное.Состояние) <> Тип("СостояниеФоновогоЗадания")
Или Обновленное.Состояние <> СостояниеФоновогоЗадания.Завершено Тогда
ВызватьИсключение "Успешное завершение собственного задания не подтверждено";
КонецЕсли;
Сообщения = Обновленное.ПолучитьСообщенияПользователю(Ложь);
Если ТипЗнч(Сообщения) <> Тип("ФиксированныйМассив") Или Сообщения.Количество() <> 1 Тогда
ВызватьИсключение "Не получено ровно одно собственное сообщение";
КонецЕсли;
Для Каждого Сообщение Из Сообщения Цикл
Если ТипЗнч(Сообщение) <> Тип("СообщениеПользователю")
Или ТипЗнч(Сообщение.Текст) <> Тип("Строка") Тогда
ВызватьИсключение "Получен не учебный текст сообщения";
КонецЕсли;
СвоеСообщение = СтрНачинаетсяС(Сообщение.Текст, "Пауза85|" + Ключ + "|интервал, мс: ");
Если ТипЗнч(СвоеСообщение) <> Тип("Булево") Или СвоеСообщение <> Истина Тогда
ВызватьИсключение "Сообщение не относится к своему ключу и измерению";
КонецЕсли;
Результат85 = Сообщение.Текст;
КонецЦикла;
Исключение
Согласие85 = Ложь;
Остановка85 = Истина;
Результат85 = "STOP: успешный результат не подтвержден; задание могло продолжить работу. Повтора и отмены нет.";
ВызватьИсключение;
КонецПопытки;
#Иначе
ВызватьИсключение "Нужен толстый управляемый клиент и собственная обычная форма";
#КонецЕсли
КонецПроцедуры
Штатно открыть собственную обычную форму
Конфигурация → Модуль управляемого приложения
Толстый управляемый клиент
Процедура ПриНачалеРаботыСистемы()
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если Метаданные.ИспользоватьОбычныеФормыВУправляемомПриложении <> Истина Тогда
ВызватьИсключение "Не подготовлено собственное учебное приложение";
КонецЕсли;
Форма = ПолучитьОбщуюФорму("Пауза85", , Новый УникальныйИдентификатор());
Если ТипЗнч(Форма) <> Тип("Форма") Тогда
ВызватьИсключение "Получена не своя обычная форма";
КонецЕсли;
Форма.Открыть();
#Иначе
ВызватьИсключение "Запустите собственный толстый клиент в управляемом режиме";
#КонецЕсли
КонецПроцедуры
Разбор по шагам
Подготовьте свой пустой стенд и три полных блока кода. Настоящее событие запуска приложения откроет обычную форму; событие ее кнопки проверит версию, собственные маркеры, путь, фактические типы и явно отмеченное согласие.
Кнопка запрещает повтор до запуска, создает настоящий UUID и строковый ключ. Массив передает 1500 и этот ключ в точном порядке двух параметров экспортированной серверной процедуры. Выполнить возвращает объект задания, а не результат измерения.
Только внутри задания считываются UTC до и после ВызватьПаузу(Интервал). 1500 — целое неотрицательное число миллисекунд. Разность этих двух фактических чисел включается в одно сообщение вместе с ключом и исходным интервалом.
Форма ровно один раз вызывает ОжидатьЗавершенияВыполнения(10): здесь 10 означает секунды. Присвоенный возврат — обновленный объект задания. Проверяются настоящий UUID, ключ, имя метода и состояние Завершено; возврат из ожидания сам по себе не означает успех.
Только затем читаются сообщения обновленного задания без удаления. Фактически требуется ФиксированныйМассив ровно из одного СообщениеПользователю со строковым текстом и префиксом своего ключа/интервала. Полученный текст попадает в свое поле, без выдуманного готового числа.
Как проверить результат
До команды согласие должно быть явно отмечено; после команды оно снято. Остановка85 остается Истина и на положительном пути. Повтор в том же экземпляре формы запрещен.
Положительный результат начинается Пауза85|, содержит фактический ключ, интервал 1500, два числовых отсчета UTC и их разность в миллисекундах. Это ожидаемое ручное наблюдение в будущем стенде, не результат уже выполненного опыта.
UUID обновленного задания совпадает с удержанным UUID запущенного. Ключ и полное имя УчебнаяПауза85.Измерить85 совпадают; состояние именно Завершено. Ошибка, отмена или все еще активное задание — STOP, не успешный пример.
Ровно одно собственное сообщение показано в Результат85. Метод вызван с Ложь: сообщения не удаляются. Их сохранение платформой и история заданий не выдаются за полностью бесписьменную операцию.
UTC — обычные часы, не монотонный секундомер. Разность может отличаться от 1500 и при коррекции часов стать отрицательной: в этом случае текст объясняет сдвиг часов, а не объявляет ошибку паузы.
Ожидаемый результат
Ожидаемый результат будущего опыта: одно успешно завершенное собственное фоновое задание, проверенный паспорт и полученный из него текст настоящего измерения в своей форме. Точное время, успешное завершение за 10 секунд и точность планировщика не гарантируются. В 1С код не запускался.
На что обратить внимание
Доступность ВызватьПаузу в толстом клиенте не разрешает вызывать его прямо из кнопки или обычного клиентского обращения на сервер. Здесь допустимый источник исполнения — штатно созданное фоновое задание.
В файловой базе одновременно исполняется только одно фоновое задание. Другие задания могут задержать запуск; выполнение через внешнее COM-соединение для этого опыта не подходит. Не заменяйте создание задания вызовом Измерить85 из формы.
Значение 1500 у ВызватьПаузу измеряется в миллисекундах; 10 у ОжидатьЗавершенияВыполнения — в секундах. Старый ОжидатьЗавершения без ограничения не используется. Нет цикла опроса, повторного запуска и ожидания из другого фонового задания.
Истекшее ожидание может вернуть еще активный объект. Исключение в задании не превращается автоматически в успешный возврат результата. Сначала проверяется фактическое состояние обновленного объекта, только потом его сообщения.
После ошибки нет отмены, удаления сообщений, повторов, отката или обращения к менеджеру для выяснения состояния. Пользователь видит STOP с честным предупреждением о неизвестном результате; фоновое задание могло продолжить работу.
УстановитьЗапретЗасыпанияКомпьютера не относится к этому desktop-опыту и не вызывается. Отрицательная разность UTC не доказывает неисправность паузы; точные 1500, монотонность и нижняя граница замера не обещаются.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.