Использование метода "ТекущаяДата()
- Конфигурации должны быть рассчитаны на работу в условиях, когда часовой пояс на серверном компьютере не совпадает с реальным часовым поясом пользователей информационной базы. Например, с сервером, расположенным в Москве, работают сотрудники компании из Владивостока, и при этом все операции в системе должны выполняться по местному времени (Владивостока). Такой сценарий работы часто востребован в клиент-серверных информационных базах и в прикладных решениях в модели сервиса (SaaS).
2.1. Во всех серверных процедурах и функциях вместо функции ТекущаяДата, которая возвращает дату и время серверного компьютера, следует использовать функцию ТекущаяДатаСеанса, которая приводит время сервера к часовому поясу пользовательского сеанса.
2.2. В тех случаях, когда требуется «универсальная» отметка времени, не зависящая от часового пояса текущего сеанса пользователя, в контексте которого выполняется серверный вызов, следует использовать функцию УниверсальноеВремя
. Например, для определения момента перезаполнения закешированных данных, для получения времени последнего выполнения фонового задания и т.п.
2.3. При использовании методов платформы, возвращающих локальную дату серверного компьютера, следует приводить ее либо к универсальному времени, либо к времени пользовательского сеанса.
Например:
ДатаАктуальностиУниверсальная = УниверсальноеВремя(ПолнотекстовыйПоиск.ДатаАктуальности());
ДатаАктуальности = МестноеВремя(ДатаАктуальностиУниверсальная, ЧасовойПоясСеанса());
3.1. В клиентском коде использование функции ТекущаяДата также недопустимо. Это требование обусловлено тем, что текущее время, вычисленное в клиентском и серверном коде, не должно различаться. Например, с сервером, расположенным в Москве, работают пользователи из Киева. Функция ТекущаяДата
для клиентского компьютера возвращает 10:00, а для сервера – 11:00. В то же время, функция ТекущаяДатаСеанса вернет на сервере 10:00, если в информационной базе установлено киевское время (с помощью метода УстановитьЧасовойПоясИнформационнойБазы). Как правило, вместо вызова функции ТекущаяДата
на клиенте необходимо:
- передавать с сервера на клиент время и дату, приведенную к часовому поясу пользовательского сеанса;
- при работе с документами на клиенте, использовать дату документа.
3.2. В алгоритме закрытия месяца с клиента на сервер передается дата, по которой далее определяется, какой месяц будет закрываться.
Неправильно:
&НаКлиенте
Процедура КомандаОткрытьЗакрытиеМесяца(Команда)
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
ТекДата = ТекущаяДата(); // вызов ТекущаяДата() на клиенте
Иначе
ТекДата = ТекущиеДанные.Дата;
КонецЕсли;
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ПериодРегистрации", ТекДата);
ОткрытьФорму("Обработка.ЗакрытиеМесяца.Форма.Форма", ПараметрыФормы, ЭтаФорма);
КонецПроцедуры
а затем в форме обработки:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЗаполнитьЗначенияСвойств(Объект, Параметры);
Если Не ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
Объект.ПериодРегистрации = НачалоМесяца(ТекущаяДата());
КонецЕсли;
...
КонецПроцедуры
Правильно перенести получение текущей даты на сервер:
&НаКлиенте
Процедура КомандаОткрытьЗакрытиеМесяца(Команда)
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
ТекДата = Неопределено; // нет вызова ТекущаяДата() на клиенте
Иначе
ТекДата = ТекущиеДанные.Дата;
КонецЕсли;
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ПериодРегистрации", ТекДата);
ОткрытьФорму("Обработка.ЗакрытиеМесяца.Форма.Форма", ПараметрыФормы, ЭтаФорма);
и в форме обработки использовать для этого функцию ТекущаяДатаСеанса
:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЗаполнитьЗначенияСвойств(Объект, Параметры);
Если Не ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
Объект.ПериодРегистрации = НачалоМесяца(ТекущаяДатаСеанса());
КонецЕсли;
3.3. При работе с документами следует рассмотреть возможность использования даты самого документа вместо текущей даты. Например, в реализации подбора номенклатуры в табличную часть документа, в форму подбора из клиентского кода передается дата расчетов для вывода цен и остатков на эту дату.
Неправильно:
&НаКлиенте
Процедура ПодборТовары(Команда)
ПараметрыПодбора = Новый Структура;
ДатаРасчетов = ?(НачалоДня(Объект.Дата) = НачалоДня(ТекущаяДата()),
Неопределено, Объект.Дата); // вызов ТекущаяДата() на клиенте
ПараметрыПодбора.Вставить("ДатаРасчетов", ДатаРасчетов);
...
ОткрытьФорму("Обработка.ПодборНоменклатуры.Форма.Форма", ПараметрыПодбора,
ЭтаФорма, УникальныйИдентификатор);
Правильно передавать на сервер дату документа, а вычисление даты расчетов выполнять на сервере:
&НаКлиенте
Процедура ПодборТовары(Команда)
ПараметрыПодбора = Новый Структура;
ПараметрыПодбора.Вставить("ДатаРасчетов", Объект.Дата);
...
ОткрытьФорму("Обработка.ПодборНоменклатуры.Форма.Форма", ПараметрыПодбора, ЭтаФорма, УникальныйИдентификатор);
КонецПроцедуры
4 . Исключения из правил 2 и 3 возможны в отдельных, обоснованных случаях, когда требуется использовать действительно текущее время серверного компьютера. Такие исключения должны быть обоснованы в тексте комментария к вызову.
5 . Следует избегать в коде одной процедуры (функции) многократного обращения к функции ТекущаяДатаСеанса (ТекущаяДата)
, так как возвращаемые значения будут отличаться друг от друга. Например, неправильно:
ДатаПоследнегоОповещения = ТекущаяДатаСеанса();
ДатаСледующегоОповещения = РассчитатьДату() + ТекущаяДатаСеанса();
правильно использовать ранее рассчитанные дату и время:
ДатаПоследнегоОповещения = ТекущаяДатаСеанса();
ДатаСледующегоОповещения = РассчитатьДату() + ДатаПоследнегоОповещения;
Экранирование кода
// sonar:ForbiddenMethodCurrentDate:off
// sonar:ForbiddenMethodCurrentDate:on