Loading
Настройка и обслуживание организации Salesforce
Пример кода с регионально отформатированными данными

Пример кода с регионально отформатированными данными

Просмотрите примеры кода, обрабатывающего данные, которые можно форматировать на основе региона пользователя. Узнайте, как код может взломаться, если он зависит от определенного формата для дат, времени и валют. Ознакомьтесь с примерами решения этих проблем посредством стандартных методов обработки данных данных.

Требуемые версии

Доступно в версиях: Salesforce Classic и Lightning Experience
Доступно в версиях: все версии

Форматы валюты, даты, времени, даты и времени, целого числа, имени и адреса могут меняться при изменении региона пользователем. При включении региональных форматов международных компонентов Юникода (ICU) форматы даты, времени, даты и времени, целого числа и валюты меняются для некоторых регионов.

Рассмотрим некоторые примеры кода, обрабатывающие данные типы данных и ошибки, которые могут произойти, если мы не используем регионально-нейтральные методы в коде.

Извлечение компонентов даты

В данном примере мы хотим проверить дату: 12 октября 2021 года. Чтобы пример был простым, мы отображаем только часть процесса, где код проверяет значения месяца, дня и года. Значение месяца должно быть меньше или равно 12. Значение дня должно быть меньше или равно 31. А значение года должно содержать ровно 4 цифры. Только даты, прошедшие все три теста, потом извлекаются в соответствующие значения для дополнительной обработки.

Ниже указан пример, использующий классы схемы Apex и совпадения для определения даты. Сопоставление схем предполагает формат даты ММ/дд/ггг.

Date myDate = Date.newInstance(2021, 10, 20);
String formattedDate = myDate.format();
 
//Simple regex not having all validations for days in months nor accounting for leap year
Pattern datePattern = Pattern.compile('(0?[1-9]|1[0-2])\\/(0?[1-9]|[2][0-9]|3[01])\\/([0-9]{4})');
Matcher matcher = datePattern.matcher(formattedDate);
 
if(matcher.matches()) {
   Integer day = Integer.valueOf((matcher.group(1))); //10
   Integer month = Integer.valueOf((matcher.group(2))); //20
   Integer year = Integer.valueOf((matcher.group(3))); //2021
   // Further validation logic for max days in month/ leap year and post processing
}

Код Apex форматирует дату в соответствии с регионом пользователя контекста. В данном примере пользователь контекста выбрал регион «Испанский (США) [es_US]».

Если региональные форматы ICU включены, эта проверка не выполняется. Формат ICU для региона пользователя отличается от соответствующего формата Инструментального набора для разработки Java-приложений Oracle (JDK).

  • Короткий формат даты JDK для es_US: 10/20/2021
  • Короткий формат даты ICU для es_US: 20/10/2021

Метод format() класса Apex Date возвращает дату в виде строки посредством региона пользователя контекста. В данном случае, поскольку региональные форматы ICU включены, а регион пользователя является es_US, возвращается 20/10/2021.

Код потом использует размещение в выводе даты для назначения значений месяца, дня и года в формате ММ/дд/ггг. Таким образом, код назначает 20 месяцем, а поскольку 20 больше 12, совпадение схемы неправильно определяет недействительность этой даты.

Во избежание подобного рода проблем используйте встроенные методы Apex для извлечения обязательных значений. В данном случае month(), day() и year().

Ниже указан пример использования этих методов для установки значений месяца, дня и года.

Date myDate = Date.newInstance(2021, 10, 20);

// assign month, day, and year values for validation
Integer month = myDate.month(); //10
Integer day = myDate.day(); //20
Integer year = myDate.year(); //2021

// Further validation logic

Проверка значения даты и времени

Данный пример Apex использует метод Datetime.parse для создания даты и времени из строки. Переданное значение соответствует региональному формату JDK для региона «Английский (США) [en_US]».

Эта проверка не выполняется при включении региональных форматов ICU, поскольку формат даты и времени для en_US отличается в JDK и ICU. Формат ICU содержит запятую после даты.

  • Формат даты и времени JDK для es_US: 14.10.2011 11:46
  • Формат даты и времени ICU для es_US: 14.10.2011, 11:46
Datetime dt = DateTime.parse('10/14/2011 11:46 AM');
String myDtString = dt.format();
system.assertEquals(myDtString, '10/14/2011, 11:46 AM');

Чтобы исправить эту проблему, обновите переданное значение в региональном формате ICU. Если внешняя система передает значение, обратитесь к отправителю для обновления формата исходных данных. При любой возможности попросите отправителя отправить дату в регионально-нейтральном формате. Рекомендуем обрабатывать обновления формата таким образом, поскольку регионально-нейтральные форматы не требуют обновления кода при изменении формата.

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

Ниже указаны два распространенных метода, используемых для форматирования даты и времени в Apex. При использовании двух этих методов, итоговые дата и время будут регионально-нейтральными: они отображаются в выбранном регионе пользователя. Дополнительные сведения о методах, доступных для всех форматов, см. в Справочном руководстве Apex.

  • Извлеките компоненты даты в отдельные параметры: год, месяц, день, часы, минуты и секунды. Потом, чтобы создать регионально- нейтральную дату, используйте метод DateTime.newInstanceGMT() класса Datetime Apex.
    //Before using the code below, set the year, month, day, hour, minutes, and seconds components 
    //by extracting values from the passed date and complete any necessary validation
    
    //set the datetime value by passing the parameters 
    DateTime myDt = DateTime.newInstanceGMT(year, month, day, hour, minutes, seconds);
    
  • Переформатируйте переданные данные в стандартном формате даты гггг-ММ-дд ЧЧ:мм:сс в региональном часовом поясе. Потом, чтобы создать регионально-нейтральную дату, используйте метод valueOf(String dateTimeString) класса Datetime.
    //Before using the code below, convert the passed datetime data to a string in the format yyyy-MM-dd HH:mm:ss 
    //and assign that value to the stringDate parameter
    
    //set the datetime value by passing the string 
    DateTime myDt = date.valueOf(stringDate);
    

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

Передача времени во внешнюю систему

В данном простом примере событие происходит в 15:30 по Гринвичу 18 ноября 2021 года. Мы хотим передать дату и время как отдельные значения во внешнюю систему.

//create Datetime to pass externally in GMT
DateTime event1_dt = DateTime.newInstanceGMT(2021, 11, 18, 15, 30, 0);

//split into event date and event time for external system
Date event1_date = event1_dt.date();
Time event1_time = event1_dt.time(); 

Этот код работает, если внешняя система ожидает дату и время в нейтральных форматах. Но что делать, если внешней системе нужны дата и время события в определенном формате? Предположим, что внешняя система ожидает дату и время в следующих форматах: 18/11/2021 и 15:30.

В этом случае, чтобы применить ожидаемые форматы к дате и времени события, используйте метод format() даты и времени.

//create Datetime to pass externally
DateTime event1_dt = DateTime.newInstance(2021, 11, 18, 15, 30, 0);

//split into event date and event time for external system, applying expected format
String event1_date = event1_dt.format('dd/MM/yyyy');
String event1_time = event1_dt.format('h:mm a');
 
Загрузка
Salesforce Help | Article