Разработка и Конфигурация · 10 мин
Как получить время сервера в 1С
Способы получить время сервера в 1С: ТекущаяДатаСеанса, ПолучитьОперативнуюОтметкуВремени, запрос к СУБД. Примеры кода, различия и типичные ошибки.
Задача получить серверное время в 1С возникает чаще, чем кажется: при синхронизации данных между базами, при записи оперативных документов, при расчёте сроков и при диагностике расхождений часовых поясов. Главная трудность в том, что привычная функция ТекущаяДата() в разных контекстах возвращает разное значение — на клиенте это время компьютера пользователя, а на сервере — время сервера приложений.
Чтобы получить именно серверное время, нужно понимать, где выполняется код: в тонком или толстом клиенте, в серверной процедуре общего модуля, в веб-клиенте или в фоновом задании. От этого зависит выбор функции и способ передачи значения на клиент, если оно нужно пользователю.
Ниже разобраны основные способы: функция ТекущаяДатаСеанса(), оперативная отметка времени, выполнение кода на сервере через общий модуль, запрос к СУБД и проверка полученного результата. Отдельно рассмотрены типичные ошибки, из-за которых в документах появляется «неправильное» время.
Различие клиентского и серверного времени в 1С
В клиент-серверной архитектуре 1С код выполняется в двух местах: на клиенте (компьютер пользователя) и на сервере приложений 1С:Предприятия. У каждой стороны свои системные часы, и они могут расходиться на секунды и даже минуты, если настройки времени на машинах не синхронизированы.
Функция ТекущаяДата() возвращает время той машины, где выполняется код. В клиентской процедуре формы — время компьютера пользователя, в серверной процедуре — время сервера. Именно поэтому прямой вызов ТекущаяДата() в модуле формы не гарантирует получение серверного времени.
Функция ТекущаяДатаСеанса() ведёт себя иначе: она учитывает часовой пояс сеанса и возвращает дату, приведённую к поясу пользователя, но вычисленную на сервере. В файловом варианте базы различий между этими функциями практически нет, поскольку клиент и «сервер» — один и тот же компьютер.
Получение времени через ТекущаяДатаСеанса()
Самый простой и рекомендуемый способ — вызвать ТекущаяДатаСеанса() в серверном контексте. Для этого создают общий модуль с включённым флагом «Сервер» (и при необходимости «Вызов сервера»), а в нём — экспортную функцию, возвращающую дату.
// Общий модуль СерверноеВремя (флаги: Сервер, Вызов сервера)
Функция ПолучитьВремяСервера() Экспорт
Возврат ТекущаяДатаСеанса();
КонецФункции
// Вызов из клиентской формы:
ДатаСервера = СерверноеВремя.ПолучитьВремяСервера();
Сообщить("Время сервера: " + ДатаСервера);Если код уже выполняется на сервере — например, в модуле объекта документа при проведении или в серверной процедуре формы с директивой &НаСервере — дополнительный общий модуль не нужен: вызывайте ТекущаяДатаСеанса() напрямую.
Обратите внимание: функция возвращает дату с точностью до секунды. Если база работает в нескольких часовых поясах, результат приводится к поясу сеанса, а не к «физическому» времени сервера — для расследования расхождений это важно учитывать.
Точное время через оперативную отметку времени
Когда секунд недостаточно — например, при высокочастотной регистрации событий обмена — используют функцию ТекущаяУниверсальнаяДатаВМиллисекундах() или ПолучитьОперативнуюОтметкуВремени(). Первая возвращает универсальное время (UTC) в миллисекундах с начала эпохи Unix, вторая — значение типа «ОперативнаяОтметкаВремени», которое платформа использует для упорядочивания изменений в планах обмена.
&НаСервере
Функция ПолучитьТочноеВремяСервера()
МиллисекундыUTC = ТекущаяУниверсальнаяДатаВМиллисекундах();
// Перевод в дату: 01.01.0001 + смещение
ДатаUTC = Дата(1,1,1) + (МиллисекундыUTC / 1000) - СмещениеUnix;
Возврат ДатаUTC;
КонецФункцииУниверсальное время удобно тем, что не зависит от часовых поясов: два сервера в разных регионах вернут сопоставимые значения. Для отображения пользователю его приводят к местному времени с учётом смещения пояса сеанса.
Ограничение: ПолучитьОперативнуюОтметкуВремени() предназначена для внутренней упорядоченности, а не для показа человеку — преобразовывать её в обычную дату для интерфейса не стоит.
Запрос времени напрямую к СУБД
В некоторых сценариях нужно время не сервера приложений 1С, а сервера базы данных — это разные машины, и часы на них могут расходиться. Типичный пример — проверка корректности записи дат в регистры или диагностика рассинхронизации.
Получить время СУБД можно через запрос, если конфигурация позволяет выполнить произвольный запрос к таблице, либо через внешние средства: консоль SQL Server Management Studio, pgAdmin для PostgreSQL или командную строку.
-- Microsoft SQL Server
SELECT GETDATE() AS ServerTime;
-- PostgreSQL
SELECT now() AS server_time;
-- IBM DB2
SELECT CURRENT TIMESTAMP FROM SYSIBM.SYSDUMMY1;Из кода 1С прямой SQL-запрос к служебным функциям СУБД выполнить штатно нельзя — язык запросов 1С таких конструкций не поддерживает. Поэтому сравнение времени СУБД и сервера приложений обычно делают административными инструментами, а не встроенным языком.
Передача серверного времени на клиент
Частая практическая задача — показать пользователю серверное время в форме, например для контроля срока действия заявки. Прямой вызов серверной функции из клиентского кода возможен только через общий модуль с флагом «Вызов сервера» или через серверную процедуру формы.
- 1Создайте общий модуль, включите флаги «Сервер» и «Вызов сервера»
- 2Добавьте экспортную функцию, возвращающую ТекущаяДатаСеанса()
- 3В клиентской процедуре формы вызовите функцию модуля и запишите результат в реквизит формы
- 4При необходимости обновляйте значение по таймеру через ПодключитьОбработчикОжидания с разумным интервалом
- 5Проверьте результат в тонком и веб-клиенте
Если время нужно обновлять непрерывно, не запрашивайте сервер каждую секунду — это создаёт лишнюю нагрузку. Оптимальный подход: получить серверное время один раз, запомнить разницу с клиентскими часами и дальше вычислять отображаемое время локально, периодически сверяясь с сервером.
В веб-клиенте каждый серверный вызов — это сетевой запрос, поэтому схема с однократным получением и локальным пересчётом особенно важна для отзывчивости интерфейса.
Проверка результата и диагностика расхождений
После реализации получения серверного времени стоит убедиться, что значения корректны. Самый простой тест — вывести рядом ТекущаяДата() на клиенте и ТекущаяДатаСеанса() с сервера и сравнить. Расхождение в пределах пары секунд — норма, минуты и часы — признак проблемы с настройкой времени на машинах или часовых поясов.
Как проверить результат
Не более нескольких секунд
Минуты и более — проверьте синхронизацию часов на машинах
Совпадает с поясом сеанса пользователя
Смещение на целые часы — проверьте настройку пояса ИБ
Значение монотонно растёт
Скачки назад — возможна некорректная синхронизация NTP на сервере
Для устойчивой синхронизации часов на серверах используют службу времени Windows (w32time) или NTP-демон в Linux. Настройка единого источника точного времени для сервера приложений, сервера СУБД и рабочих станций устраняет большинство проблем с расхождением дат.
Типичные ошибки и ограничения
Самая распространённая ошибка — вызов ТекущаяДата() в клиентской процедуре с уверенностью, что это серверное время. В файловой базе такой код «работает», и проблема вскрывается только после перехода на клиент-серверный вариант, когда у пользователей начинают появляться документы с разъезжающимся временем.
Ещё одно ограничение: в файловом варианте понятие «серверное время» фактически отсутствует — код всегда работает на машине пользователя. Если конфигурация должна одинаково вести себя в обоих режимах, используйте ТекущаяДатаСеанса() повсеместно: в файловом режиме она вернёт локальное время, в клиент-серверном — серверное, и логика не сломается.
Что важно запомнить
Серверное время получают через ТекущаяДатаСеанса() в серверном контексте — общем модуле с флагом «Сервер». Для точности выше секунды используют универсальную дату в миллисекундах. ТекущаяДата() на клиенте возвращает время машины пользователя, а не сервера. Часы сервера приложений и СУБД синхронизируют через NTP.
Частые вопросы
Чем ТекущаяДата() отличается от ТекущаяДатаСеанса()?
ТекущаяДата() возвращает системное время машины, где выполняется код: на клиенте — время компьютера пользователя, на сервере — время сервера. ТекущаяДатаСеанса() вычисляется на сервере и приводится к часовому поясу сеанса пользователя, поэтому безопаснее для клиент-серверных решений.
Почему в файловой базе обе функции возвращают одинаковое значение?
В файловом варианте нет отдельного сервера приложений — весь код выполняется на компьютере пользователя. Поэтому клиентское и «серверное» время совпадают, и различия между функциями незаметны до перехода на клиент-серверный режим.
Как получить серверное время с точностью до миллисекунд?
Используйте ТекущаяУниверсальнаяДатаВМиллисекундах() — она возвращает число миллисекунд в UTC. Значение можно пересчитать в дату, прибавив его к начальной дате отсчёта, либо хранить как число для точного сравнения событий.
Можно ли получить время сервера SQL прямо из кода 1С?
Штатными средствами языка запросов 1С — нет, функции СУБД вроде GETDATE() в запросах недоступны. Время сервера базы данных проверяют через инструменты администрирования СУБД либо через внешние компоненты и COM-подключения, что требует осторожности с безопасностью.
Что делать, если серверное время расходится с клиентским на несколько минут?
Проверьте настройки системного времени и часовых поясов на сервере приложений и рабочих станциях, затем настройте синхронизацию всех машин с единым NTP-источником. Если смещение ровно на целые часы — проблема почти наверняка в настройке часового пояса сеанса или информационной базы.
Безопасно ли часто опрашивать сервер ради обновления часов в форме?
Нежелательно: каждый вызов — сетевой запрос и нагрузка на сервер. Получите серверное время один раз при открытии формы, вычислите разницу с клиентскими часами и дальше обновляйте отображение локально, периодически сверяясь с сервером с интервалом в несколько минут.