Форматирование данных
=====================
Для форматирования вывода Yii предоставляет класс, преобразующий данные в человеко-понятный формат.
[[yii\i18n\Formatter]] это класс-помощник, который зарегистрирован как
[компонент приложения](structure-application-components.md), по умолчанию под именем `formatter`.
Он предоставляет набор методов для форматирования таких данных как дата/время, числа и другие часто используемые в целях
локализации форматы.
Formatter может быть использован двумя различными способами.
1. Напрямую, используя методы форматирования (все методы форматирования имеют префикс `as`):
```php
echo Yii::$app->formatter->asDate('2014-01-01', 'long'); // выведет: January 1, 2014
echo Yii::$app->formatter->asPercent(0.125, 2); // выведет: 12.50%
echo Yii::$app->formatter->asEmail('cebe@example.com'); // выведет: cebe@example.com
echo Yii::$app->formatter->asBoolean(true); // выведет: Yes
// он также умеет отображать null значения:
echo Yii::$app->formatter->asDate(null); // выведет: (not set)
```
2. Используя метод [[yii\i18n\Formatter::format()|format()]] и имя формата.
Этот метод также используется в виджетах наподобие [[yii\grid\GridView]] и [[yii\widgets\DetailView]], в которых
вы можете задать формат отображения данных в колонке через конфигурацию виджета.
```php
echo Yii::$app->formatter->format('2014-01-01', 'date'); // выведет: January 1, 2014
// вы также можете использовать массивы для настроек метода форматирования:
// `2` это значение для $decimals параметра метода asPercent().
echo Yii::$app->formatter->format(0.125, ['percent', 2]); // выведет: 12.50%
```
Все данные, отображаемые через компонент formatter, будут локализованы, если
[расширение PHP intl](https://www.php.net/manual/ru/book.intl.php) было установлено. Для этого вы можете настроить свойство
[[yii\i18n\Formatter::locale|locale]]. Если оно не было настроено, то в качестве локали будет использован
[[yii\base\Application::language|язык приложения]]. Подробнее смотрите в разделе «[интернационализация](tutorial-i18n.md)».
Компонент форматирования будет выбирать корректный формат для даты и чисел в соответствии с локалью, включая имена
месяцев и дней недели, переведённые на текущий язык.
Форматирование дат также зависит от [[yii\i18n\Formatter::timeZone|часового пояса]], который будет взят из одноимённого свойства [[yii\base\Application::timeZone|timeZone]] приложения, если не был задан явно. В свою очередь [[yii\base\Application::timeZone|timeZone]] устанавливает / читает временную зону PHP.
Например, форматирование даты, вызванное с разной локалью, отобразит разные результаты::
```php
Yii::$app->formatter->locale = 'en-US';
echo Yii::$app->formatter->asDate('2014-01-01'); // выведет: January 1, 2014
Yii::$app->formatter->locale = 'de-DE';
echo Yii::$app->formatter->asDate('2014-01-01'); // выведет: 1. January 2014
Yii::$app->formatter->locale = 'ru-RU';
echo Yii::$app->formatter->asDate('2014-01-01'); // выведет: 1 января 2014 г.
```
> Обратите внимание, что форматирование может различаться между различными версиями библиотеки ICU, собранных с PHP,
> а также на основе того установлено ли [расширение PHP intl](https://www.php.net/manual/ru/book.intl.php) или нет.
> Таким образом, чтобы гарантировать, что ваш сайт будет одинаково отображать данные во всех окружениях рекомендуется
> установить расширение PHP intl во всех окружениях и проверить, что версия библиотеки ICU совпадает.
> См. также: [Настройка PHP окружения для интернационализации](tutorial-i18n.md#setup-environment).
>
> Отметим также, что даже если установлено расширение PHP intl, форматирование даты и времени для значений года >=2038
> или <=1901 на 32-ух разрядных системах будет обращаться к реализации PHP, которая не обеспечивает локализованные
> имена месяца и дня, потому что в этом случае intl будет использовать 32-ух битный UNIX timestamp. На 64-битной системе
> intl formatter будет работать во всех случаях, если, конечно, intl был установлен.
Настройка форматирования
--------------------------------------------------------------
Форматы по умолчанию, используемые в методах форматирования, можно настраивать через свойства
[[yii\i18n\Formatter|класса форматирования]]. Вы можете задать форматирование по умолчанию для всего приложения, настроив
компонент `formatter` в вашей [конфигурации приложения](concept-configurations.md#application-configurations). Ниже
приведён пример конфигурации. Чтобы узнать больше о доступных свойствах см. [[yii\i18n\Formatter|API документацию к классу Formatter]]
и следующие подсекции.
```php
'components' => [
'formatter' => [
'dateFormat' => 'dd.MM.yyyy',
'decimalSeparator' => ',',
'thousandSeparator' => ' ',
'currencyCode' => 'EUR',
],
],
```
Форматирование значений даты и времени
-----------------------------------------------------------------------
Класс форматирования предоставляет различные методы для форматирования значений даты и времени. Например:
- [[yii\i18n\Formatter::asDate()|date]] — значение будет отформатировано как дата, например `January 01, 2014`.
- [[yii\i18n\Formatter::asTime()|time]] — значение будет отформатировано как время, например `14:23`.
- [[yii\i18n\Formatter::asDatetime()|datetime]] — значение будет отформатировано как дата и время, например
`January 01, 2014 14:23`.
- [[yii\i18n\Formatter::asTimestamp()|timestamp]] — значение будет отформатировано как
[unix timestamp](https://ru.wikipedia.org/wiki/UNIX-время), например, `1412609982`.
- [[yii\i18n\Formatter::asRelativeTime()|relativeTime]] — значение будет отформатировано как временной промежуток между
заданной датой и текущим временем в человеко понятном формате, например: `1 час назад`.
- [[yii\i18n\Formatter::asDuration()|duration]]: значение будет отформатировано как продолжительность в человеко-понятном
формате, например `1 день, 2 минуты`.
Форматирование даты и времени для методов [[yii\i18n\Formatter::asDate()|date]], [[yii\i18n\Formatter::asTime()|time]] и
[[yii\i18n\Formatter::asDatetime()|datetime]] может быть задано глобально через конфигурацию свойств форматирования
[[yii\i18n\Formatter::$dateFormat|$dateFormat]], [[yii\i18n\Formatter::$timeFormat|$timeFormat]] и
[[yii\i18n\Formatter::$datetimeFormat|$datetimeFormat]].
По умолчанию, форматирование использует сокращенный формат, который интерпретируется по-разному в зависимости от активной
в данный момент локали. Поэтому дата и время будут отформатированы наиболее часто используемым способом в стране и языке
пользователя. Доступны 4 разных сокращенных формата:
- `short` в локали `en_GB` отобразит, например, `06/10/2014` для даты и `15:58` для времени, в то время как
- `medium` будет отображать `6 Oct 2014` и `15:58:42` соответственно,
- `long` будет отображать `6 October 2014` и `15:58:42 GMT` соответственно и
- `full` будет отображать `Monday, 6 October 2014` и `15:58:42 GMT` соответственно.
Дополнительно вы можете задать специальный формат, используя синтаксис, заданный [ICU Project](https://icu.unicode.org/),
который описан в руководстве ICU по следующему адресу:
` теги. - [[yii\i18n\Formatter::asHtml()|html]] — значение будет очищено, используя [[yii\helpers\HtmlPurifier|HtmlPurifier]], с целью предотвратить XSS атаки. Вы можете задать дополнительные параметры, такие как `['html', ['Attr.AllowedFrameTargets' => ['_blank']]]`. - [[yii\i18n\Formatter::asEmail()|email]] — значение будет отформатировано как ссылка `mailto`. - [[yii\i18n\Formatter::asImage()|image]] — значение будет отформатировано как тег картинки. - [[yii\i18n\Formatter::asUrl()|url]] — значение будет отформатировано как ссылка . - [[yii\i18n\Formatter::asBoolean()|boolean]] — значение форматируется как логическое. По умолчанию `true` будет отображено как `Yes` и `false` как `No`, переведенное на язык приложения. Вы можете настроить это через свойство [[yii\i18n\Formatter::booleanFormat]]. `null` значения ---------------------------------------------- Для значений `null` в PHP класс форматирования будет отображать вместо пустой строки маркер, по умолчанию это `(not set)`, переведенный на язык приложения. Вы можете настроить свойство [[yii\i18n\Formatter::nullDisplay|nullDisplay]] для установки собственного маркера. Если вы не хотите обрабатывать `null` значения, то установите свойство [[yii\i18n\Formatter::nullDisplay|nullDisplay]] в `null`.