ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

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

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

Для получения текущей даты и времени используются следующие функции:

  • ТекущаяДата() – определяет текущую (системную) дату на компьютере.
  • ТекущаяДатаСеанса() – получает текущую дату сервера, приведенную к часовому поясу сеанса пользователя.
  • ТекущаяУниверсальнаяДата() – получает текущую универсальную дату компьютера.
  • ТекущаяУниверсальнаяДатаВМиллисекундах() – получает текущую универсальную дату в миллисекундах (в UTC, начиная с 01.01.0001 00:00:00).

Отдельно нужно упомянуть функцию УниверсальноеВремя(<МестноеВремя>, <ЧасовойПояс>). Данная функция не возвращает текущую дату и время, она преобразует переданную дату и время в универсальное время с учетом часового пояса. Что позволяет решить ряд проблем при использовании прикладного решения в разных часовых поясах.

Условия работы конфигураций

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

1) С конфигурацией пользователи работают в пределах одного часового пояса. Например, база конфигурации установлена в г.Москва, пользователи, которые работают с ней, находятся в этом же часовом поясе. При этом, у них на компьютерах время может отличаться. И этот факт при разработке программного продукта обязательно нужно учитывать.

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

2) С базой данных конфигурации работают пользователи из разных часовых поясов. Например, сервер базы данных расположен в г.Москва, и с этой базой работают в реальном времени пользователи из разных городов, Калининград, Москва, Владивосток. В этом случае возникает вопрос, который связан с использованием даты и времени. Если пользователи работают в разных часовых поясах, какую дату и время нужно использовать при регистрации событий, чтобы вести учет в строгой хронологической последовательности?

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

На такие вопросы поможет ответить стандарт #std643 «Работа в разных часовых поясах» на сайте 1С:ИТС. Ссылка на стандарт: https://its.1c.ru/db/v8std/content/643/hdoc.

ТекущаяДата()

Начнем с самой популярной функции, это ТекущаяДата().

Данная функция определяет текущую (системную) дату на компьютере. Доступна как на стороне клиента, так и на стороне сервера.

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

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

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

Например, в обработке видно, что функция ТекущаяДата() на клиенте и на сервере вернула разное время, на клиенте 15:46:52, а на сервере 11:56:06. Ни часы, ни минуты, ни секунды не совпадают. Часы не совпали, так как сервер физически расположен в другом часовом поясе. Минуты и секунды не совпали, так как у клиента не включен режим автоматического получения времени, соответственно часы не синхронизированы, а настроены вручную, причем некорректно. Если проверить время у других клиентов, то, скорее всего, у всех оно будет отличаться. В этом случае попытка использования времени, полученного на стороне клиента, может привести к нарушению хронологии ведения учета, получению некорректных данных и так далее.

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

Как быть, если нужно использовать местное время клиентов для ведения учета в строгой хронологической последовательности, когда время у них не синхронизировано и может сильно отличаться?

Обратимся к статье стандарта #std643 и найдем несколько правил по решению данной проблемы:

2.1. Во всех серверных процедурах и функциях вместо функции ТекущаяДата, которая возвращает дату и время серверного компьютера, следует использовать функцию ТекущаяДатаСеанса, которая приводит время сервера к часовому поясу пользовательского сеанса.3.1. В клиентском коде использование функции ТекущаяДата также недопустимо. Это требование обусловлено тем, что текущее время, вычисленное в клиентском и серверном коде, не должно различаться.Как правило, вместо вызова функции ТекущаяДата на клиенте необходимо:передавать с сервера на клиент время и дату, приведенную к часовому поясу пользовательского сеанса;при работе с документами на клиенте, использовать дату документа.

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

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

В обработке видно, что функция ТекущаяДатаСеанса() взяла время на сервере 11:58:06 (UTC+3), учла часовой пояс клиента (UTC+7) и вернула время клиенту 15:58:06, прибавив 4 часа. Это корректное время, которое нужно использовать на стороне клиента, но никак не время 15:46:52, которое вернула функция ТекущаяДата() на стороне клиента.

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

Когда нужно использовать функцию ТекущаяДата()? Данную функцию можно использовать в следующих ситуациях:

  • Запись логов, когда важно знать, в какое время были выполнены операции на данном компьютере.
  • Напоминания пользователю, чтобы они отрабатывали в нужное время для пользователя.
  • Вычисление интервалов времени между событиями в рамках одного сеанса, например, для расчета времени выполнения каких-либо операций пользователем или обработкой.
  • Работа с сертификатами на стороне клиента для выяснения срока действия и т.д.

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

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

Данная функция получает текущую дату сервера, приведенную к часовому поясу сеанса пользователя.

При вычислении даты используется один из заданных часовых поясов в следующем приоритете:

  • Часовой пояс сеанса.
  • Часовой пояс информационной базы.
  • Часовой пояс сервера.

Функция доступна на стороне сервера и в толстом клиенте. Остальные варианты доступности можно посмотреть самостоятельно.

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

В обработке видно, что функция ТекущаяДатаСеанса() взяла время на сервере 11:58:06 (UTC+3), учла часовой пояс клиента (UTC+7) и вернула время клиенту 15:58:06, прибавив 4 часа. Это корректное время, которое нужно использовать на стороне клиента, но никак не время 15:46:52, которое вернула функция ТекущаяДата() на стороне клиента.

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

Обратившись к статье стандарта #std643 выводим правило о том, что:

2.1. Во всех серверных процедурах и функциях вместо функции ТекущаяДата, которая возвращает дату и время серверного компьютера, следует использовать функцию ТекущаяДатаСеанса, которая приводит время сервера к часовому поясу пользовательского сеанса.

Значит ли это, что каждый раз, когда необходима текущая дата на клиенте, нужно выполнять серверный вызов, обращаясь к функции ТекущаяДатаСеанса()? Конечно, нет, например, в типовых конфигурациях, которые используют БСП для решения проблемы частых серверных вызовов используется функция ДатаСеанса() из общего модуля ОбщегоНазначенияКлиент. Данную функцию рекомендовано использовать вместо функции ТекущаяДата().

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

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

Подводим итоги

Функция ТекущаяДата() может на стороне клиента возвращать некорректное время по отношению ко времени на сервере, а это в некоторых ситуациях может привести к нарушению хронологии ведения учета, получению некорректных данных и т.д.. По стандарту #std643 для решения подобных проблем необходимо использовать функцию ТекущаяДатаСеанса(). Но так как она выполняется только на стороне сервера и чтобы избежать частых серверных вызовов, обращаясь к данной функции, можно использовать функцию ДатаСеанса() из общего модуля ОбщегоНазначенияКлиент БСП.

Рекомендация: При разработке прикладных решений используйте стандарты и методики, описанные на сайте 1С:ИТС.

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?
ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

Ваганов Сергей, эксперт в области разработки прикладных решений на платформе 1С:Предприятие, преподаватель-методист CORS Academy и автор курса «Разработчик 1С с нуля до профессионала»

ТекущаяДата() или ТекущаяДатаСеанса(): что выбрать?

Подписывайтесь:

CORS Клуб – сообщество и образовательная среда для специалистов из IT-сферы https://cors.su/klub/

Канал руководителей IT компаний и подразделений, CIO, СDO, CDTO https://t.me/cio_channel

CIO. Сообщество IT руководителей https://vk.com/cio_club

Начать дискуссию