The NumberFormatter class

(PHP 5 >= 5.3.0, PHP 7, PHP 8, PECL intl >= 1.0.0)

Введение

Программы хранят и оперируют числами используя, не зависящее от локали, бинарное представление. Когда же они выводятся на экран или печатаются, они конвертируются в строки в соответствии с требованиями локали. К примеру, число 12345.67 выведется как "12,345.67" в локали US, как "12 345,67" во французской локали и как "12.345,67" в немецкой.

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

Для денежных единиц вы можете использовать тип форматирования денежных единиц, который возвращает строку с отформатированным числом и символом денежной единицы. Естественно NumberFormatter не знает о курсах обмена, так что для всех денежных единиц будет возвращено одно и то же число. К примеру, для числа 9988776.65 результат будет такой:

  • 9 988 776,65 € для Франции
  • 9.988.776,65 € для Германии
  • $9,988,776.65 для США

Для форматирования процентных величин используется свой тип форматирования. При таком форматировании число 0.75 будет выведено как 75%.

Для более сложного форматирования, например для разбора числа, используется форматирование основанное на наборе правил.

Обзор классов

NumberFormatter {
/* Методы */
public __construct(string $locale, int $style, string $pattern = ?)
public static create(string $locale, int $style, string $pattern = ?): NumberFormatter
public formatCurrency(float $value, string $currency): string|false
public format(int|float $value, int $type = ?): string
public getAttribute(int $attr): int
public getErrorCode(): int
public getErrorMessage(): string
public getLocale(int $type = ?): string
public getPattern(): string
public getSymbol(int $attr): string
public getTextAttribute(int $attr): string
public parseCurrency(string $value, string &$currency, int &$position = ?): float
public parse(string $value, int $type = ?, int &$position = ?): mixed
public setAttribute(int $attr, int $value): bool
public setPattern(string $pattern): bool
public setSymbol(int $attr, string $value): bool
public setTextAttribute(int $attr, string $value): bool
}

Предопределённые константы

Данные стили используются функцией numfmt_create() для определения типа форматирования.

NumberFormatter::PATTERN_DECIMAL (int)
Формат с десятичной точкой заданный шаблоном
NumberFormatter::DECIMAL (int)
Формат с десятичной точкой
NumberFormatter::CURRENCY (int)
денежный формат
NumberFormatter::PERCENT (int)
Процентный формат
NumberFormatter::SCIENTIFIC (int)
Научный формат
NumberFormatter::SPELLOUT (int)
Разобранный формат на основе правил
NumberFormatter::ORDINAL (int)
Числительный формат на основе правил
NumberFormatter::DURATION (int)
Формат длительности на основе правил
NumberFormatter::PATTERN_RULEBASED (int)
Формат на основе правил по шаблону
NumberFormatter::CURRENCY_ACCOUNTING (int)
Формат валюты для учёта, например, ($3.00) для отрицательной суммы в валюте вместо -$3.00. Доступно с PHP 7.4.1 и ICU 53.
NumberFormatter::DEFAULT_STYLE (int)
Формат по умолчанию для локали
NumberFormatter::IGNORE (int)
Псевдоним для PATTERN_DECIMAL

Данные константы определяют как будут разобраны или отформатированы числа. Их необходимо передавать функциям numfmt_format() и numfmt_parse().

NumberFormatter::TYPE_DEFAULT (int)
Тип определяется типом переменной
NumberFormatter::TYPE_INT32 (int)
Форматирование/разбор как 32-битного целого
NumberFormatter::TYPE_INT64 (int)
Форматирование/разбор как 64-битного целого
NumberFormatter::TYPE_DOUBLE (int)
Форматирование/разбор как рационального (float)
NumberFormatter::TYPE_CURRENCY (int)
Форматирование/разбор как денежной единицы

Атрибут формата чисел для numfmt_get_attribute() и numfmt_set_attribute().

NumberFormatter::PARSE_INT_ONLY (int)
Разбирать только целые.
NumberFormatter::GROUPING_USED (int)
Использовать группирующий разделитель.
NumberFormatter::DECIMAL_ALWAYS_SHOWN (int)
Всегда показывать десятичную точку.
NumberFormatter::MAX_INTEGER_DIGITS (int)
Максимальное число целых цифр.
NumberFormatter::MIN_INTEGER_DIGITS (int)
Минимальное число целых цифр.
NumberFormatter::INTEGER_DIGITS (int)
Целых цифр.
NumberFormatter::MAX_FRACTION_DIGITS (int)
Максимальное число цифр после запятой.
NumberFormatter::MIN_FRACTION_DIGITS (int)
Минимальное число цифр после запятой.
NumberFormatter::FRACTION_DIGITS (int)
Число цифр после запятой.
NumberFormatter::MULTIPLIER (int)
Множитель.
NumberFormatter::GROUPING_SIZE (int)
Размер группировки.
NumberFormatter::ROUNDING_MODE (int)
Режим округления.
NumberFormatter::ROUNDING_INCREMENT (int)
Приращение округления.
NumberFormatter::FORMAT_WIDTH (int)
Ширина на которую будет дополнен вывод format().
NumberFormatter::PADDING_POSITION (int)
Позиция с которой дополнение будет иметь место. Смотрите описание констант дополнения.
NumberFormatter::SECONDARY_GROUPING_SIZE (int)
Вторичный размер группировки.
NumberFormatter::SIGNIFICANT_DIGITS_USED (int)
Использовать значащие цифры.
NumberFormatter::MIN_SIGNIFICANT_DIGITS (int)
Минимальное количество значащих цифр.
NumberFormatter::MAX_SIGNIFICANT_DIGITS (int)
Максимальное количество значащих цифр.
NumberFormatter::LENIENT_PARSE (int)
Режим снисходительны синтаксического анализа для основанных на правилах форматов.

Атрибуты текста форматирования чисел, используются в numfmt_get_text_attribute() и numfmt_set_text_attribute().

NumberFormatter::POSITIVE_PREFIX (int)
Положительный префикс.
NumberFormatter::POSITIVE_SUFFIX (int)
Положительный суффикс.
NumberFormatter::NEGATIVE_PREFIX (int)
Отрицательный префикс.
NumberFormatter::NEGATIVE_SUFFIX (int)
Отрицательный суффикс.
NumberFormatter::PADDING_CHARACTER (int)
Символ для дополнения строки.
NumberFormatter::CURRENCY_CODE (int)
Код денежной единицы ISO.
NumberFormatter::DEFAULT_RULESET (int)
Набор правил по умолчанию. Доступно только для форматирования на основе правил.
NumberFormatter::PUBLIC_RULESETS (int)
Публичный набор правил. Доступно только для форматирования на основе правил. Этот атрибут доступен только на чтение. Публичный набор правил возвращается в виде строки, в которой каждый набор правил отделен точкой с запятой (;).

Символы форматирования чисел для numfmt_get_symbol() и numfmt_set_symbol().

NumberFormatter::DECIMAL_SEPARATOR_SYMBOL (int)
Десятичный разделитель.
NumberFormatter::GROUPING_SEPARATOR_SYMBOL (int)
Разделитель групп.
NumberFormatter::PATTERN_SEPARATOR_SYMBOL (int)
Символ разделителя в шаблона.
NumberFormatter::PERCENT_SYMBOL (int)
Символ процента.
NumberFormatter::ZERO_DIGIT_SYMBOL (int)
Ноль.
NumberFormatter::DIGIT_SYMBOL (int)
Символ представляющий цифру в шаблоне.
NumberFormatter::MINUS_SIGN_SYMBOL (int)
Знак минус.
NumberFormatter::PLUS_SIGN_SYMBOL (int)
Знак плюс.
NumberFormatter::CURRENCY_SYMBOL (int)
Символ обозначения денежной единицы.
NumberFormatter::INTL_CURRENCY_SYMBOL (int)
The international currency symbol.
NumberFormatter::MONETARY_SEPARATOR_SYMBOL (int)
Денежный разделитель.
NumberFormatter::EXPONENTIAL_SYMBOL (int)
Символ степени десяти.
NumberFormatter::PERMILL_SYMBOL (int)
Символ промилле.
NumberFormatter::PAD_ESCAPE_SYMBOL (int)
Экранирование символа заполнителя.
NumberFormatter::INFINITY_SYMBOL (int)
Символ бесконечности.
NumberFormatter::NAN_SYMBOL (int)
Символ NAN (Not-a-number, не-число).
NumberFormatter::SIGNIFICANT_DIGIT_SYMBOL (int)
Символ значащей цифры.
NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL (int)
Разделитель групп для денежного формата.

Режимы округления для numfmt_get_attribute() и numfmt_set_attribute() с атрибутом NumberFormatter::ROUNDING_MODE.

NumberFormatter::ROUND_CEILING (int)
Округление в сторону положительной бесконечности.
NumberFormatter::ROUND_DOWN (int)
Округление вниз.
NumberFormatter::ROUND_FLOOR (int)
Округление в сторону отрицательной бесконечности.
NumberFormatter::ROUND_HALFDOWN (int)
Округление в сторону "ближайшего соседа" кроме случаев, когда они на одинаковом расстоянии. В этом случае округление вниз.
NumberFormatter::ROUND_HALFEVEN (int)
Округление в сторону "ближайшего соседа" кроме случаев, когда они на одинаковом расстоянии. В этом случае округление к чётному значению.
NumberFormatter::ROUND_HALFUP (int)
Округление в сторону "ближайшего соседа" кроме случаев, когда они на одинаковом расстоянии. В этом случае округление вверх.
NumberFormatter::ROUND_UP (int)
Округление вверх.

Значения позиции дополнения для numfmt_get_attribute() и numfmt_set_attribute() с атрибутом NumberFormatter::PADDING_POSITION.

NumberFormatter::PAD_AFTER_PREFIX (int)
Символы дополнения вставляются после префикса.
NumberFormatter::PAD_AFTER_SUFFIX (int)
Символы дополнения вставляются после суффикса.
NumberFormatter::PAD_BEFORE_PREFIX (int)
Символы дополнения вставляются до префикса.
NumberFormatter::PAD_BEFORE_SUFFIX (int)
Символы дополнения вставляются до суффикса.

Содержание

add a note add a note

User Contributed Notes 6 notes

up
34
giorgio dot liscio at email dot it
13 years ago
this class seems to be painful: it is not, formatting and parsing are highly customizable, but what you probably need is really simple:

if you want to localize a number use:

<?php
$a
= new \NumberFormatter("it-IT", \NumberFormatter::DECIMAL);
echo
$a->format(12345.12345) . "<br>"; // outputs 12.345,12
$a->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, 0);
$a->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 100); // by default some locales got max 2 fraction digits, that is probably not what you want
echo $a->format(12345.12345) . "<br>"; // outputs 12.345,12345
?>

if you want to print money use:

<?php
$a
= new \NumberFormatter("it-IT", \NumberFormatter::CURRENCY);
echo
$a->format(12345.12345) . "<br>"; // outputs €12.345,12
?>

if you have money data stored as (for example) US dollars and you want to print them using the it-IT notation, you need to use

<?php
$a
= new \NumberFormatter("it-IT", \NumberFormatter::CURRENCY);
echo
$a->formatCurrency(12345, "USD") . "<br>"; // outputs $ 12.345,00 and it is formatted using the italian notation (comma as decimal separator)
?>

another useful example about currency (how to obtain the currency name by a locale string):

<?php
$frontEndFormatter
= new \NumberFormatter("it-IT", \NumberFormatter::CURRENCY);
$adminFormatter = new \NumberFormatter("en-US", \NumberFormatter::CURRENCY);
$symbol = $adminFormatter->getSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL); // got USD
echo $frontEndFormatter->formatCurrency(12345.12345$symbol) . "<br>";
?>
up
6
sudheer at binaryvibes dot co dot in
13 years ago
Sample script to print number in English.

<?php
$f
= new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo
$f->format(123456);

?>

Produces the result:
one hundred twenty-three thousand four hundred fifty-six
up
2
stan at dragnev dot ca
3 years ago
Here's an example of how to use PATTERN_DECIMAL to print a number with two fraction digits, use () for negative numbers and pad to five characters to the left of the decimal point, using spaces as the padding character:

<?php

$fmt
= new NumberFormatter("en-CA", NumberFormatter::PATTERN_DECIMAL, "* #####.00 ;(* #####.00)");
echo
$fmt->format(-45.1);

// Outputs: "  (45.10)"

?>

Note that the ; in the pattern denotes the beginning of a subpattern, which is used for negative numbers. Hence the brackets around the pattern after the semicolon.
up
1
AF
3 years ago
Please pay attention to the Arabic decimal separator (https://en.wikipedia.org/wiki/Decimal_separator#Other_numeral_systems).

All the following conditions are true:
<?php
(new \NumberFormatter("ar_AE", \NumberFormatter::DEFAULT_STYLE))->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL) === '٫';
(new \
NumberFormatter("ar_AE", \NumberFormatter::DEFAULT_STYLE))->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL) == '٫';

(new \
NumberFormatter("ar_AE", \NumberFormatter::DEFAULT_STYLE))->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL) !== ',';
(new \
NumberFormatter("ar_AE", \NumberFormatter::DEFAULT_STYLE))->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL) != ',';
?>
up
0
Joey
7 years ago
Be warned that this class sometimes lacks sufficient error output. I recently instantiated it while invalid pattern to the constructor.

    php -r '$nf = new \NumberFormatter("tlh-KX.UTF8", \NumberFormatter::IGNORE, "{,,#;#}");var_dump($nf->format(5));'

    Fatal error: Call to a member function format() on null in Command line code on line 1

Rather than emitting an error message or throwing an exception null is returned after calling new.

I'm not sure if it's fixed in PHP 7 but it's something to watch out for. Make sure you check your parameters very closely.
up
-4
Adam
7 years ago
Good to know Numberformatter::SPELLOUT using soft hypens.

So, if you want to avoid it use preg_replace:

<?php
$azaz
= new NumberFormatter("hu-HU", NumberFormatter::SPELLOUT);
$text = preg_replace('~\x{00AD}~u', '', $azaz->format(123456));
print
$text;
?>
Output without preg_replace:
egy-­száz-­huszon-­három-­ezer négy-­száz-­ötven-­hat

Output with preg_replace:
egyszázhuszonháromezer négyszázötvenhat
To Top