Перейти к содержанию

Использование метода "ТекущаяДата()

  1. Конфигурации должны быть рассчитаны на работу в условиях, когда часовой пояс на серверном компьютере не совпадает с реальным часовым поясом пользователей информационной базы. Например, с сервером, расположенным в Москве, работают сотрудники компании из Владивостока, и при этом все операции в системе должны выполняться по местному времени (Владивостока). Такой сценарий работы часто востребован в клиент-серверных информационных базах и в прикладных решениях в модели сервиса (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