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%.

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

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

class NumberFormatter {
/* Методы */
public __construct(string $locale, int $style, ?string $pattern = null)
public static create(string $locale, int $style, ?string $pattern = null): ?NumberFormatter
public formatCurrency(float $amount, string $currency): string|false
public format(int|float $num, int $type = NumberFormatter::TYPE_DEFAULT): string|false
public getAttribute(int $attribute): int|float|false
public getErrorCode(): int
public getErrorMessage(): string
public getLocale(int $type = ULOC_ACTUAL_LOCALE): string|false
public getPattern(): string|false
public getSymbol(int $symbol): string|false
public getTextAttribute(int $attribute): string|false
public parseCurrency(string $string, string &$currency, int &$offset = null): float|false
public parse(string $string, int $type = NumberFormatter::TYPE_DOUBLE, int &$offset = null): int|float|false
public setAttribute(int $attribute, int|float $value): bool
public setPattern(string $pattern): bool
public setSymbol(int $symbol, string $value): bool
public setTextAttribute(int $attribute, 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

User Contributed Notes 7 notes

up
37
giorgio dot liscio at email dot it
11 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
2
stan at dragnev dot ca
1 year 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
3
sudheer at binaryvibes dot co dot in
11 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
0
gwyneth dot llewelyn at gwynethllewelyn dot net
14 days ago
When using the `NumberFormatter` class for pretty-printing currency in PHP 7.3 and 8+, it's not clear from the documentation that you can use the empty string "" as the locale for the constructor, and that will retrieve the default locale (whatever it has been set to in your environment).

`formatCurrency()`, by contrast, does not accept the empty string for the default currency symbol; it will display a 'generic' currency symbol instead (¤).

Tested with PHP 7.4.30, 8.0.21, 8.1.8 under Ubuntu Linux and 8.1.8 under macOS Big Sur (11.6.8). I tried under other alternatives (e.g. Linux running on ARM chips, PHP 7.3.3) but sadly the `NumberFormatter` library does not seem to be present (or could not be found) on those systems...
up
-1
Joey
5 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
-1
AF
1 year 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
-6
Adam
5 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