Компонент Intl

Компонент Intl

Этот компонент предоставляет доступ к данным локализации библиотеки ICU.

Caution

Заменяющий слой ограничен локалью en. Если вы хотите использовать другие локали, вам стоит установить расширение intl. Между ними не будет конфликта, так как даже если вы используете расширение, этот пакет может все еще быть полезент для доступа к данным ICU.

See also

Эта статья объясняет как использовать функции Intl как независимого компонента в любом приложении PHP. Прочитайте статью Переводы для понимания как делать интернационализацию и управлять пользовательскими локалями в приложениях Symfony.

Установка

1
$ composer require symfony/intl

Note

Если вы устанавливаете этот компонент вне приложения Symfony, вам нужно подключить файл vendor/autoload.php в вашем коде для включения механизма автозагрузки классов, предоставляемых Composer. Детальнее читайте в этой статье.

Доступ к данным ICU

Этот компонент предоставляет следующие данные ICU:

Язык и названия скриптов

Класс Languages предоставляет доступ к названиям всех языков в соответствии со списками ISO 639-1 alpha-2 и ISO 639-2 alpha-3 (2T):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Symfony\Component\Intl\Languages;

\Locale::setDefault('en');

$languages = Languages::getNames();
// ('languageCode' => 'languageName')
// => ['ab' => 'Abkhazian', 'ace' => 'Achinese', ...]

$languages = Languages::getAlpha3Names();
// ('languageCode' => 'languageName')
// => ['abk' => 'Abkhazian', 'ace' => 'Achinese', ...]

$language = Languages::getName('fr');
// => 'French'

$language = Languages::getAlpha3Name('fra');
// => 'French'

Все методы принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию имеет значение текущей локали:

1
2
3
4
5
6
7
8
9
10
11
$languages = Languages::getNames('de');
// => ['ab' => 'Abchasisch', 'ace' => 'Aceh', ...]

$languages = Languages::getAlpha3Names('de');
// => ['abk' => 'Abchasisch', 'ace' => 'Aceh', ...]

$language = Languages::getName('fr', 'de');
// => 'Französisch'

$language = Languages::getAlpha3Name('fra', 'de');
// => 'Französisch'

Если заданная локаль не существует, методы запускают MissingResourceException. В дополнение к обнаружению исключения, вы также можете проверить, является ли код заданного языка валидным:

1
$isValidLanguage = Languages::exists($languageCode);

Или, если у вас есть код языка alpha3, который вы хотите проверить:

1
$isValidLanguage = Languages::alpha3CodeExists($alpha3Code);

Вы можете преобразовывать эти коды между двубуквенными alpha2 и трехбуквенными alpha3 кодами:

1
2
3
$alpha3Code = Languages::getAlpha3Code($alpha2Code);

$alpha2Code = Languages::getAlpha2Code($alpha3Code);

Класс Scripts предоставляет доступ к необязательному четырехбуквенному коду скрипта, который может следовать коду языка, в соответствии с регистром Unicode ISO 15924 (например, HANS в zh_HANS для упрощенного китайского, иHANT в zh_HANT для традиционного китайского):

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\Intl\Scripts;

\Locale::setDefault('en');

$scripts = Scripts::getNames();
// ('scriptCode' => 'scriptName')
// => ['Adlm' => 'Adlam', 'Afak' => 'Afaka', ...]

$script = Scripts::getName('Hans');
// => 'Simplified'

Все методы принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию имеет значение локали по умолчанию:

1
2
3
4
5
$scripts = Scripts::getNames('de');
// => ['Adlm' => 'Adlam', 'Afak' => 'Afaka', ...]

$script = Scripts::getName('Hans', 'de');
// => 'Vereinfacht'

Если заданный код скрипта не существует, методы вызывают MissingResourceException. В дополенение к обнаружению исключения, вы также можете проверить, является ли заданный код скрипта валидным:

1
$isValidScript = Scripts::exists($scriptCode);

Названия стран

Класс Countries предоставляет доступ к названиям всех стран, в соответствии со списками ISO 3166-1 alpha-2 и ISO 3166-1 alpha-3 официально признанных стран и территорий:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Symfony\Component\Intl\Countries;

\Locale::setDefault('en');

$countries = Countries::getNames();
// ('alpha2Code' => 'countryName')
// => ['AF' => 'Afghanistan', 'AX' => 'Åland Islands', ...]

$countries = Countries::getAlpha3Names();
// ('alpha3Code' => 'countryName')
// => ['AFG' => 'Afghanistan', 'ALA' => 'Åland Islands', ...]

$country = Countries::getName('GB');
// => 'United Kingdom'

$country = Countries::getAlpha3Name('NOR');
// => 'Norway'

Все методы принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию имеет значение текущей локали:

1
2
3
4
5
6
7
8
9
10
11
$countries = Countries::getNames('de');
// => ['AF' => 'Afghanistan', 'EG' => 'Ägypten', ...]

$countries = Countries::getAlpha3Names('de');
// => ['AFG' => 'Afghanistan', 'EGY' => 'Ägypten', ...]

$country = Countries::getName('GB', 'de');
// => 'Vereinigtes Königreich'

$country = Countries::getAlpha3Name('GBR', 'de');
// => 'Vereinigtes Königreich'

Если заданный код страны не существует, методы вызывают MissingResourceException. В дополнение к обнаружению исключения, вы также можете проверить, является ли заданный код страны валидным:

1
$isValidCountry = Countries::exists($alpha2Code);

Или, если у вас код страны alpha3, вы можете проверить:

1
$isValidCountry = Countries::alpha3CodeExists($alpha3Code);

Вы можете преобразовывать коды между двубуквенным alpha2 и трехбуквенным alpha3 кодами:

1
2
3
$alpha3Code = Countries::getAlpha3Code($alpha2Code);

$alpha2Code = Countries::getAlpha2Code($alpha3Code);

Локали

Локаль - это комбинация языка, региона и некоторых параметров, которые определяют настройки интерфейса пользователя. К примеру, "китайский" - это язык, а zh_Hans_MO - локаль для "китайского" (языка) + "упрощенный" (скрипт) + "Макау Китай" (регион). Класс Locales предоставляет доступ к названиям всех локалей:

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\Intl\Locales;

\Locale::setDefault('en');

$locales = Locales::getNames();
// ('localeCode' => 'localeName')
// => ['af' => 'Afrikaans', 'af_NA' => 'Afrikaans (Namibia)', ...]

$locale = Locales::getName('zh_Hans_MO');
// => 'Chinese (Simplified, Macau SAR China)'

Все методы принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию имеет значение текущей локали:

1
2
3
4
5
$locales = Locales::getNames('de');
// => ['af' => 'Afrikaans', 'af_NA' => 'Afrikaans (Namibia)', ...]

$locale = Locales::getName('zh_Hans_MO', 'de');
// => 'Chinesisch (Vereinfacht, Sonderverwaltungsregion Macau)'

Если заданный код локали не существует, методы вызывают MissingResourceException. В дополнение к обнаружению исключения, вы также можете проверить, является ли заданный код локали валидным:

1
$isValidLocale = Locales::exists($localeCode);

Валюты

Класс Currencies предоставляет доступ к названиям всех валют, а также к их некоторой информации (символ, цифры после запятой и т.д.):

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\Intl\Currencies;

\Locale::setDefault('en');

$currencies = Currencies::getNames();
// ('currencyCode' => 'currencyName')
// => ['AFN' => 'Afghan Afghani', 'ALL' => 'Albanian Lek', ...]

$currency = Currencies::getName('INR');
// => 'Indian Rupee'

$symbol = Currencies::getSymbol('INR');
// => '₹'

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

1
2
3
4
5
6
7
// Индийская рупия определяет одинаковое значение для обоих
$fractionDigits = Currencies::getFractionDigits('INR');         // returns: 2
$cashFractionDigits = Currencies::getCashFractionDigits('INR'); // returns: 2

// Шведская крона определяет разные значения
$fractionDigits = Currencies::getFractionDigits('SEK');         // returns: 2
$cashFractionDigits = Currencies::getCashFractionDigits('SEK'); // returns: 0

5.3

Метод getCashFractionDigits() был представлен в Symfony 5.3.

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

1
2
3
4
5
6
7
8
9
// Индийская рупия определяет одинаковое значение для обоих
$roundingIncrement = Currencies::getRoundingIncrement('INR');         // returns: 0
$cashRoundingIncrement = Currencies::getCashRoundingIncrement('INR'); // returns: 0

// Канадский доллар определяет разные значения, так как они избавились от
// мелких монет (в 1 и 2 цента), и цены в наличных должны округляться до
// 5 центов (к примеру, если цена - 7.42, вы платите 7.40; если 7.48 - то 7.50)
$roundingIncrement = Currencies::getRoundingIncrement('CAD');         // returns: 0
$cashRoundingIncrement = Currencies::getCashRoundingIncrement('CAD'); // returns: 5

5.3

Метод getCashRoundingIncrement() был представлен в Symfony 5.3.

Все методы, кромеgetFractionDigits(), getCashFractionDigits(), getRoundingIncrement() и getCashRoundingIncrement()) принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию является текущей локалью по умолчанию:

1
2
3
4
5
$currencies = Currencies::getNames('de');
// => ['AFN' => 'Afghanischer Afghani', 'EGP' => 'Ägyptisches Pfund', ...]

$currency = Currencies::getName('INR', 'de');
// => 'Indische Rupie'

Если заданный код валюты не существует, методы вызывают MissingResourceException. В дополнение к обнаружению исключения, вы также можете проверить, является ли заданный код валюты валидным:

1
$isValidCurrency = Currencies::exists($currencyCode);

Часовые пояса

Класс Timezones предоставляет несколько утилит, связанных с часовыми поясами. Во-первых, вы можете получить название и значения всех часовых поясов на всех языках:

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\Intl\Timezones;

\Locale::setDefault('en');

$timezones = Timezones::getNames();
// ('timezoneID' => 'timezoneValue')
// => ['America/Eirunepe' => 'Acre Time (Eirunepe)', 'America/Rio_Branco' => 'Acre Time (Rio Branco)', ...]

$timezone = Timezones::getName('Africa/Nairobi');
// => 'East Africa Time (Nairobi)'

Все методы принимают локаль перевода в качестве последнего необязательного параметра, который по умолчанию является текушей локалью по умолчанию:

1
2
3
4
5
$timezones = Timezones::getNames('de');
// => ['America/Eirunepe' => 'Acre-Zeit (Eirunepe)', 'America/Rio_Branco' => 'Acre-Zeit (Rio Branco)', ...]

$timezone = Timezones::getName('Africa/Nairobi', 'de');
// => 'Ostafrikanische Zeit (Nairobi)'

Вы также можете получить все существующие часовые пояса в заданной стране. Метод forCountryCode() возвращает один или более ID часовых поясов, которые вы можете перевести на любую локаль с помощью метода getName(), показанного ранее:

1
2
3
// в отличие от кодов языков, коды стран всегда используют верхний регистр (CL = Chile)
$timezones = Timezones::forCountryCode('CL');
// => ['America/Punta_Arenas', 'America/Santiago', 'Pacific/Easter']

Обратный просмотр также возможен, благодаря методу getCountryCode(), который возвращает код страны, которой принадлежит ID заданного часового пояса:

1
2
$countryCode = Timezones::getCountryCode('America/Vancouver');
// => $countryCode = 'CA' (CA = Canada)

Смещение времени UTC/GMT всех часовых поясов предоставляется getRawOffset() (который возврвщает целое число, представляющее сообой смещение времени в секундах) и getGmtOffset() (который возвращает строку, представляющую собой смещение времени для отображения пользователям):

1
2
3
4
5
6
7
$offset = Timezones::getRawOffset('Etc/UTC');              // $offset = 0
$offset = Timezones::getRawOffset('America/Buenos_Aires'); // $offset = -10800
$offset = Timezones::getRawOffset('Asia/Katmandu');        // $offset = 20700

$offset = Timezones::getGmtOffset('Etc/UTC');              // $offset = 'GMT+00:00'
$offset = Timezones::getGmtOffset('America/Buenos_Aires'); // $offset = 'GMT-03:00'
$offset = Timezones::getGmtOffset('Asia/Katmandu');        // $offset = 'GMT+05:45'

Смещение времени часового пояса может различаться во времени из-за практики летнего времени (DST). По умолчанию эти методы используют PHP-функцию time(), чтобы получить текущее значение смещения времени часового пояса, но вы можете передать временную метку в качестве вторых аргументов, чтобы получить смещение времени в любой заданный момент времени:

1
2
3
4
5
// В 2019, период летнего времени в Мадриде (Испания) проходил с 31 марта до 27 октября
$offset = Timezones::getRawOffset('Europe/Madrid', strtotime('March 31, 2019'));   // $offset = 3600
$offset = Timezones::getRawOffset('Europe/Madrid', strtotime('April 1, 2019'));    // $offset = 7200
$offset = Timezones::getGmtOffset('Europe/Madrid', strtotime('October 27, 2019')); // $offset = 'GMT+02:00'
$offset = Timezones::getGmtOffset('Europe/Madrid', strtotime('October 28, 2019')); // $offset = 'GMT+01:00'

Строчная репрезентация смещения времени GMT может различаться в зависимости от локали, так что вы можете передать локаль в качестве третьего необязательного аргумента:

1
2
$offset = Timezones::getGmtOffset('Europe/Madrid', strtotime('October 28, 2019'), 'ar'); // $offset = 'غرينتش+01:00'
$offset = Timezones::getGmtOffset('Europe/Madrid', strtotime('October 28, 2019'), 'dz'); // $offset = 'ཇི་ཨེམ་ཏི་+01:00'

Если заданный ID часового пояса не существует, методы вызовут MissingResourceException. В дополнение к обнаружению исключения, вы также можете проверить, является ли заданный код часового пояса валидным:

1
$isValidTimezone = Timezones::exists($timezoneId);