При разработке прикладных решений, в которых пользователи будут работать с одной информационной базой из разных часовых поясов, можно допустить ошибку, которая приведет к нарушению хронологии ведения учета, получению некорректных данных и т.д.
Разберем, какие существуют функции получения текущей даты и времени, отдельно рассмотрим функцию УниверсальноеВремя() и выясним в каких случаях их нужно использовать.
Для получения текущей даты и времени используются следующие функции:
- ТекущаяДата() – определяет текущую (системную) дату на компьютере.
- ТекущаяДатаСеанса() – получает текущую дату сервера, приведенную к часовому поясу сеанса пользователя.
- ТекущаяУниверсальнаяДата() – получает текущую универсальную дату компьютера.
- ТекущаяУниверсальнаяДатаВМиллисекундах() – получает текущую универсальную дату в миллисекундах (в UTC, начиная с 01.01.0001 00:00:00).
Отдельно нужно упомянуть функцию УниверсальноеВремя(<МестноеВремя>, <ЧасовойПояс>). Данная функция не возвращает текущую дату и время, она преобразует переданную дату и время в универсальное время с учетом часового пояса, что позволяет решить ряд проблем при использовании прикладного решения в разных часовых поясах.
Функции ТекущаяДата() и ТекущаяДатаСеанса() мы уже рассмотрели ранее.
В этой статье рассмотрим оставшиеся три функции: ТекущаяУниверсальнаяДата(), ТекущаяУниверсальнаяДатаВМиллисекундах() и УниверсальноеВремя().
Условия работы конфигураций
Современные прикладные решения, разрабатываемые на платформе 1С:Предприятия, должны поддерживать корректную работу пользователей из разных часовых поясов с единой информационной базой.
Например, сервер 1С и база данных расположены в Москве, и с этой базой работают в реальном времени пользователи из разных городов, к примеру, Калининград, Москва, Владивосток.
Для организации такой возможности технологическая платформа 1С:Предприятие предоставляет ряд функций.
ТекущаяУниверсальнаяДата()
Функция ТекущаяУниверсальнаяДата() получает текущую универсальную дату компьютера, приведенную к часовому поясу GMT+00:00.
Доступна на стороне сервера и в толстом клиенте, остальные варианты доступности можете посмотреть самостоятельно.
Функция ТекущаяУниверсальнаяДата() возвращает текущее время сервера приведенное к часовому поясу GMT+00:00, гарантируя одинаковый результат для всех клиентов независимо от их часового пояса и времени, которое, возможно, настроено некорректно на их компьютерах.
Нужно учитывать, что данная функция изменяет только часы согласно часовому поясу, и если на сервере время не синхронизировано или настроено некорректно, то минуты и секунды не синхронизируются и останутся такими же, как на сервере.
Полученный результат можно сравнить с информацией на сайте https://time.is/GMT.
Данную функцию можно использовать в разных случаях, например:
- При настройке обмена, между информационными базами, расположенными в разных часовых поясах, если обмен привязан ко времени.
- При возможном переносе сервера в другой часовой пояс.
- При использовании нескольких серверов, расположенных в разных часовых поясах.
УниверсальноеВремя()
Данная функция не возвращает текущую дату и время, она преобразует переданную дату и время в универсальное время с учетом часового пояса, что позволяет решить ряд проблем при использовании прикладного решения в разных часовых поясах.
Доступна как на стороне клиента, так и на стороне сервера.
У функции есть два параметра:
- МестноеВремя – обязательный параметр
- ЧасовойПояс – необязательный параметр.
Обратимся к статье стандарта #std643:
2.2. В тех случаях, когда требуется «универсальная» отметка времени, не зависящая от часового пояса текущего сеанса пользователя, в контексте которого выполняется серверный вызов, следует использовать функцию УниверсальноеВремя. Например, для определения момента перезаполнения закешированных данных, для получения времени последнего выполнения фонового задания и т.п.
2.3. При использовании методов платформы, возвращающих локальную дату серверного компьютера, следует приводить ее либо к универсальному времени, либо к времени пользовательского сеанса. Например:
ДатаАктуальностиУниверсальная = УниверсальноеВремя(ПолнотекстовыйПоиск.ДатаАктуальности());
ДатаАктуальности = МестноеВремя(ДатаАктуальностиУниверсальная, ЧасовойПоясСеанса());
Данную функцию можно использовать, например:
- При определении момента перезаполнения закешированных данных.
- При получении времени последнего выполнения фонового задания
- При вычислении корректной хронологической последовательности событий, возникающих в разных часовых поясах, в единой информационной базе и т.д.
Разберем каждый параметр функции УниверсальноеВремя(), чтобы понять смысл описанных в стандарте #std643 правил.
В обязательный параметр МестноеВремя передается дата со временем, которая будет преобразована в универсальную дату и время с учетом часового пояса компьютера. Функция без параметра ЧасовойПояс может быть вызвана на стороне клиента, где в качестве часового пояса будет браться часовой пояс компьютера, с которого вызывается данная функция.
Если необходимо использовать другой часовой пояс, отличный от текущего часового пояса компьютера, с которого вызывается данная функция, то используется параметр ЧасовойПояс.
При использовании параметра ЧасовойПояс функцию можно использовать только на сервере, в режиме «Толстого клиента» или во внешнем соединении. В качестве значения выступает текстовое название часового пояса или время в формате GMT{+/-}h[h][:mm].
Рассмотрим небольшой пример. Клиентам, находящимся в разных часовых поясах в одно и тоже местное время, не в один и тот же момент, а в одно и тоже местное время, например, в 12:00:00, функция вернет универсальное время с учетом часового пояса, при этом минуты и секунды останутся такими же как на сервере.
Например, «Тонкий клиент» запущен в городе Барнаул, местное время 12:00:00, функция вернет универсальное 05:00:00 приведенное к часовому поясу GMT+00:00.
Для всех остальных часовых поясов, когда местное время будет 12:00:00, данная функция вернет универсальное время, приведенное к часовому поясу GMT+00:00. Расчет универсального времени представлен в таблице.
Такое поведение можно использовать, когда пользователи одной информационной базы из разных городов создают и записывают один и тот же тип документа. Далее, на едином складе записанные документы нужно обрабатывать строго по порядку. Вопрос о том, чей документ для обработки брать первым, поможет решить данная функция.
Например, запись документов осуществлена в следующих городах по местному времени:
После преобразования времени с помощью функции УниверсальноеВремя(), получим следующую последовательность.
Благодаря функции УниверсальноеВремя() можно выстроить операции в правильной хронологической последовательности.
УниверсальноеВремя() в типовых конфигурациях
В типовых конфигурациях, которые используют БСП, для решения проблемы частых серверных вызовов используется функция ДатаУниверсальная() из общего модуля ОбщегоНазначенияКлиент. Данную функцию рекомендовано использовать вместо функции УниверсальноеВремя().
Суть данной функции заключается в получении поправки к времени сеанса и поправки к универсальному времени при старте сеанса. В дальнейшем на стороне клиента идет обращение к функции ТекущаяДата() плюс поправки к времени сеанса и поправки к универсальному времени. Это позволяет получить результат, близкий к результату функции УниверсальноеВремя() без частых серверных вызовов.
ТекущаяУниверсальнаяДатаВМиллисекундах()
Данная функция получает текущую универсальную дату в миллисекундах (в UTC, начиная с 01.01.0001 00:00:00).
Доступна как на стороне клиента, так и на стороне сервера.
Данная функция возвращает число миллисекунд, прошедших с 1 января 0001 года 00 часов 00 минут 00 секунд.
Чтобы полученное число миллисекунд представить в виде привычной нам даты и времени, конечно, без миллисекунд, первоначально нужно избавиться от миллисекунд, оставив только секунды, разделив число на 1000, и полученный результат прибавить к пустой дате.
Чаще всего данную функцию используют для замера временных интервалов в миллисекундах. Например, замерим время выполнения запроса, в результате получим результат, равный 847 миллисекундам.
Подводим итоги
Функция ТекущаяУниверсальнаяДата() возвращает текущее время сервера, приведенное к часовому поясу GMT+00:00, гарантируя одинаковый результат для всех клиентов независимо от их часового пояса и времени, которое, возможно, настроено некорректно на их компьютерах.
Нужно учитывать, что данная функция изменяет только часы согласно часовому поясу, и если на сервере время не синхронизировано, и настроено некорректно, то минуты и секунды не синхронизируются, а останутся такими же, как на сервере.
Функция УниверсальноеВремя() не возвращает текущую дату и время, она преобразует переданную дату и время в универсальное время с учетом часового пояса. Это позволяет решить ряд проблем при использовании прикладного решения в разных часовых поясах.
Функция ТекущаяУниверсальнаяДатаВМиллисекундах() возвращает число миллисекунд, прошедших с 1 января 0001 года 00 часов 00 минут 00 секунд. Чаще всего ее используют для замера временных интервалов в миллисекундах.
Ваганов Сергей, эксперт в области разработки прикладных решений на платформе 1С:Предприятие, преподаватель-методист CORS Academy и автор курса «Разработчик 1С с нуля до профессионала»