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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

Давайте разберем два надежных способа решения этой задачи.

Способ 1: Использование стандартной функции ТекущаяДатаСеанса()

Это самый простой и предпочтительный метод для современных конфигураций на управляемых формах. Платформа 1С предоставляет специальную функцию ТекущаяДатаСеанса(), которая создана именно для таких целей.

В чем ее особенность? Эта функция возвращает дату и время, которые были актуальны на сервере в момент установки сеанса пользователя. Это значение одинаково для всего сеанса работы и не зависит от того, где вызывается функция — на клиенте или на сервере. Это гарантирует единообразие временных меток для всех документов и операций, созданных в рамках одной сессии.

Как использовать:

Использовать ее так же просто, как и ТекущаяДата(). В задачах, где требуется программное изменение форм, в коде клиентской процедуры можно написать:


&НаКлиенте
Процедура УстановитьДатуДокумента()
    // Получаем дату сеанса, которая соответствует времени сервера
    ДатаДляДокумента = ТекущаяДатаСеанса();
    
    // Присваиваем ее реквизиту формы
    Объект.Дата = ДатаДляДокумента;
    
    Сообщить("Документу установлена дата сеанса: " + ДатаДляДокумента);
КонецПроцедуры

Когда стоит применять этот метод:

Этот способ идеален для большинства повседневных задач:

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

Способ 2: Создание собственной функции в общем модуле

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

Разберем по шагам, как это сделать.

  1. Создание общего модуля

    Если у вас еще нет подходящего общего модуля, создайте новый. Назовем его, например, ОбщегоНазначенияСерверныеВызовы. Важно правильно настроить его свойства.

  2. Настройка свойств общего модуля

    Откройте палитру свойств созданного модуля и установите следующие флаги:

    • Сервер — этот флаг указывает, что код модуля компилируется и выполняется на стороне сервера 1С.
    • Вызов сервера — этот ключевой флаг разрешает обращаться к экспортным процедурам и функциям этого модуля из клиентского кода. Платформа автоматически организует "мост" для такого вызова.

    Остальные флаги (Клиент (управляемое приложение), Внешнее соединение и др.) можно оставить без изменений, если они не требуются для других задач.

  3. Написание серверной функции

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

    
    ' Обязательно указываем директиву компиляции, хотя для серверного модуля это избыточно,
    ' но является хорошим тоном для читаемости кода.
    &НаСервере
    Функция ПолучитьАктуальнуюДатуСервера() Экспорт
        
        // Так как эта функция выполняется на сервере, 
        // ТекущаяДата() вернет именно системное время сервера.
        Возврат ТекущаяДата();
        
    КонецФункции
    

    Ключевое слово Экспорт делает эту функцию доступной для вызова из других модулей, в том числе и с клиента (благодаря флагу `Вызов сервера`).

  4. Вызов функции из клиентского кода

    Теперь из любого клиентского кода, например, из модуля формы, можно легко получить актуальное время сервера:

    
    &НаКлиенте
    Процедура ЗаписатьВремяСобытия(Команда)
        // Обращаемся к нашему общему модулю и его экспортной функции
        ТочноеСерверноеВремя = ОбщегоНазначенияСерверныеВызовы.ПолучитьАктуальнуюДатуСервера();
        
        Сообщить("Событие зафиксировано в: " + ТочноеСерверноеВремя);
        
        // Далее можно использовать это значение для записи в лог, регистр и т.д.
    КонецПроцедуры
    

Когда стоит применять этот метод:

Важный нюанс: Каждый такой вызов — это полноценное обращение с клиента на сервер. При редком использовании это не оказывает никакого влияния на производительность. Однако не стоит использовать этот метод в циклах или в событиях, которые срабатывают очень часто (например, ПриИзменении поля ввода), так как это может создать избыточную нагрузку на сеть и сервер.

Сравнение подходов: что и когда использовать?

Давайте подведем итог и сравним оба метода, чтобы вы могли выбрать наиболее подходящий для вашей задачи.

ТекущаяДатаСеанса()

Собственная серверная функция

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

← На главную