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

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

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

Способы получить время сервера в 1С: ТекущаяДатаСеанса, ПолучитьОперативнуюОтметкуВремени, запрос к СУБД. Примеры кода, различия и типичные ошибки.

Задача получить серверное время в 1С возникает чаще, чем кажется: при синхронизации данных между базами, при записи оперативных документов, при расчёте сроков и при диагностике расхождений часовых поясов. Главная трудность в том, что привычная функция ТекущаяДата() в разных контекстах возвращает разное значение — на клиенте это время компьютера пользователя, а на сервере — время сервера приложений.

Чтобы получить именно серверное время, нужно понимать, где выполняется код: в тонком или толстом клиенте, в серверной процедуре общего модуля, в веб-клиенте или в фоновом задании. От этого зависит выбор функции и способ передачи значения на клиент, если оно нужно пользователю.

Ниже разобраны основные способы: функция ТекущаяДатаСеанса(), оперативная отметка времени, выполнение кода на сервере через общий модуль, запрос к СУБД и проверка полученного результата. Отдельно рассмотрены типичные ошибки, из-за которых в документах появляется «неправильное» время.

Различие клиентского и серверного времени в 1С

В клиент-серверной архитектуре 1С код выполняется в двух местах: на клиенте (компьютер пользователя) и на сервере приложений 1С:Предприятия. У каждой стороны свои системные часы, и они могут расходиться на секунды и даже минуты, если настройки времени на машинах не синхронизированы.

Функция ТекущаяДата() возвращает время той машины, где выполняется код. В клиентской процедуре формы — время компьютера пользователя, в серверной процедуре — время сервера. Именно поэтому прямой вызов ТекущаяДата() в модуле формы не гарантирует получение серверного времени.

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

Получение времени через ТекущаяДатаСеанса()

Самый простой и рекомендуемый способ — вызвать ТекущаяДатаСеанса() в серверном контексте. Для этого создают общий модуль с включённым флагом «Сервер» (и при необходимости «Вызов сервера»), а в нём — экспортную функцию, возвращающую дату.

bsl
// Общий модуль СерверноеВремя (флаги: Сервер, Вызов сервера)
Функция ПолучитьВремяСервера() Экспорт
    Возврат ТекущаяДатаСеанса();
КонецФункции

// Вызов из клиентской формы:
ДатаСервера = СерверноеВремя.ПолучитьВремяСервера();
Сообщить("Время сервера: " + ДатаСервера);

Если код уже выполняется на сервере — например, в модуле объекта документа при проведении или в серверной процедуре формы с директивой &НаСервере — дополнительный общий модуль не нужен: вызывайте ТекущаяДатаСеанса() напрямую.

Обратите внимание: функция возвращает дату с точностью до секунды. Если база работает в нескольких часовых поясах, результат приводится к поясу сеанса, а не к «физическому» времени сервера — для расследования расхождений это важно учитывать.

Точное время через оперативную отметку времени

Когда секунд недостаточно — например, при высокочастотной регистрации событий обмена — используют функцию ТекущаяУниверсальнаяДатаВМиллисекундах() или ПолучитьОперативнуюОтметкуВремени(). Первая возвращает универсальное время (UTC) в миллисекундах с начала эпохи Unix, вторая — значение типа «ОперативнаяОтметкаВремени», которое платформа использует для упорядочивания изменений в планах обмена.

bsl
&НаСервере
Функция ПолучитьТочноеВремяСервера()
    МиллисекундыUTC = ТекущаяУниверсальнаяДатаВМиллисекундах();
    // Перевод в дату: 01.01.0001 + смещение
    ДатаUTC = Дата(1,1,1) + (МиллисекундыUTC / 1000) - СмещениеUnix;
    Возврат ДатаUTC;
КонецФункции

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

Ограничение: ПолучитьОперативнуюОтметкуВремени() предназначена для внутренней упорядоченности, а не для показа человеку — преобразовывать её в обычную дату для интерфейса не стоит.

Запрос времени напрямую к СУБД

В некоторых сценариях нужно время не сервера приложений 1С, а сервера базы данных — это разные машины, и часы на них могут расходиться. Типичный пример — проверка корректности записи дат в регистры или диагностика рассинхронизации.

Получить время СУБД можно через запрос, если конфигурация позволяет выполнить произвольный запрос к таблице, либо через внешние средства: консоль SQL Server Management Studio, pgAdmin для PostgreSQL или командную строку.

sql
-- 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. 1
    Создайте общий модуль, включите флаги «Сервер» и «Вызов сервера»
  2. 2
    Добавьте экспортную функцию, возвращающую ТекущаяДатаСеанса()
  3. 3
    В клиентской процедуре формы вызовите функцию модуля и запишите результат в реквизит формы
  4. 4
    При необходимости обновляйте значение по таймеру через ПодключитьОбработчикОжидания с разумным интервалом
  5. 5
    Проверьте результат в тонком и веб-клиенте

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

В веб-клиенте каждый серверный вызов — это сетевой запрос, поэтому схема с однократным получением и локальным пересчётом особенно важна для отзывчивости интерфейса.

Проверка результата и диагностика расхождений

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

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

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

Разница клиентского и серверного времени
Норма

Не более нескольких секунд

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

Минуты и более — проверьте синхронизацию часов на машинах

Часовой пояс возвращаемой даты
Норма

Совпадает с поясом сеанса пользователя

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

Смещение на целые часы — проверьте настройку пояса ИБ

Стабильность при повторных вызовах
Норма

Значение монотонно растёт

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

Скачки назад — возможна некорректная синхронизация NTP на сервере

Для устойчивой синхронизации часов на серверах используют службу времени Windows (w32time) или NTP-демон в Linux. Настройка единого источника точного времени для сервера приложений, сервера СУБД и рабочих станций устраняет большинство проблем с расхождением дат.

Типичные ошибки и ограничения

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

Типичные ошибки
01
Вызов ТекущаяДата() на клиенте вместо серверной функции — в документах появляется время компьютера пользователя
02
Частые серверные вызовы из таймера формы — лишняя нагрузка на сервер и сеть
03
Игнорирование часового пояса сеанса — у пользователей из других регионов время сдвигается на часы
04
Сравнение оперативной отметки времени с обычной датой напрямую — типы несовместимы, сравнение даёт неверный результат
05
Ожидание миллисекундной точности от ТекущаяДатаСеанса() — функция возвращает значение с точностью до секунды

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

Итог

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

Серверное время получают через ТекущаяДатаСеанса() в серверном контексте — общем модуле с флагом «Сервер». Для точности выше секунды используют универсальную дату в миллисекундах. ТекущаяДата() на клиенте возвращает время машины пользователя, а не сервера. Часы сервера приложений и СУБД синхронизируют через NTP.

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

Чем ТекущаяДата() отличается от ТекущаяДатаСеанса()?

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

Почему в файловой базе обе функции возвращают одинаковое значение?

В файловом варианте нет отдельного сервера приложений — весь код выполняется на компьютере пользователя. Поэтому клиентское и «серверное» время совпадают, и различия между функциями незаметны до перехода на клиент-серверный режим.

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

Используйте ТекущаяУниверсальнаяДатаВМиллисекундах() — она возвращает число миллисекунд в UTC. Значение можно пересчитать в дату, прибавив его к начальной дате отсчёта, либо хранить как число для точного сравнения событий.

Можно ли получить время сервера SQL прямо из кода 1С?

Штатными средствами языка запросов 1С — нет, функции СУБД вроде GETDATE() в запросах недоступны. Время сервера базы данных проверяют через инструменты администрирования СУБД либо через внешние компоненты и COM-подключения, что требует осторожности с безопасностью.

Что делать, если серверное время расходится с клиентским на несколько минут?

Проверьте настройки системного времени и часовых поясов на сервере приложений и рабочих станциях, затем настройте синхронизацию всех машин с единым NTP-источником. Если смещение ровно на целые часы — проблема почти наверняка в настройке часового пояса сеанса или информационной базы.

Безопасно ли часто опрашивать сервер ради обновления часов в форме?

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