PHP 8.4.2 Released!

A classe NumberFormatter

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

Introdução

Programas armazenam e operam números usando uma representação binária que não depende da localidade. Ao apresentar ou imprimir um número, ele é convertido para uma string específica para a localidade. Por exemplo, o número 12345.67 é "12,345.67" nos Estados Unidos, "12 345,67" na França e "12.345,67" na Alemanha e no Brasil.

Ao invocar os métodos fornecidos pela classe NumberFormatter, pode-se formatar números, moedas, e percentagens de acordo com o especificado ou com a localidade padrão. NumberFormatter é sensível à localidade, portanto é necessário criar um novo objeto NumberFormatter para cada localidade. Métodos NumberFormatter formatam números com tipos primitivos, como 'double' e mostram o número como uma string específica para a localidade

Para moedas, pode-se usar o tipo de formato de moeda para criar um formatador que retorne uma string com o número formatado e com o sinal apropriado para a moeda. Obviamente, a classe NumberFormatter não tem ciência de taxas de câmbio, portanto, a saída é a mesma independente da moeda especificada. Isto significa que o mesmo número tem diferentes valores monteários dependendo da moeda da localidade. Se o número for 9988776.65, os resultados serão:

  • 9 988 776,65 € na França
  • 9.988.776,65 € na Alemanha
  • $9,988,776.65 nos Estados Unidos

Para formatar percentagens, deve-se criar um formatador específico da localidade com o tipo de formato de percentual. Com este formatados, uma fração decimal como 0.75 é mostrada como 75%.

Para formatações mais complexas, como números por extenso, os formatadores de número baseados em regras são utilizados.

Resumo da classe

class NumberFormatter {
/* Constantes */
public const int PATTERN_DECIMAL;
public const int DECIMAL;
public const int CURRENCY;
public const int PERCENT;
public const int SCIENTIFIC;
public const int SPELLOUT;
public const int ORDINAL;
public const int DURATION;
public const int PATTERN_RULEBASED;
public const int IGNORE;
public const int CURRENCY_ACCOUNTING;
public const int DEFAULT_STYLE;
public const int ROUND_CEILING;
public const int ROUND_FLOOR;
public const int ROUND_DOWN;
public const int ROUND_UP;
public const int ROUND_TOWARD_ZERO;
public const int ROUND_HALFEVEN;
public const int ROUND_HALFODD;
public const int ROUND_HALFDOWN;
public const int ROUND_HALFUP;
public const int PAD_BEFORE_PREFIX;
public const int PAD_AFTER_PREFIX;
public const int PAD_BEFORE_SUFFIX;
public const int PAD_AFTER_SUFFIX;
public const int PARSE_INT_ONLY;
public const int GROUPING_USED;
public const int MAX_INTEGER_DIGITS;
public const int MIN_INTEGER_DIGITS;
public const int INTEGER_DIGITS;
public const int MAX_FRACTION_DIGITS;
public const int MIN_FRACTION_DIGITS;
public const int FRACTION_DIGITS;
public const int MULTIPLIER;
public const int GROUPING_SIZE;
public const int ROUNDING_MODE;
public const int ROUNDING_INCREMENT;
public const int FORMAT_WIDTH;
public const int PADDING_POSITION;
public const int LENIENT_PARSE;
public const int POSITIVE_PREFIX;
public const int POSITIVE_SUFFIX;
public const int NEGATIVE_PREFIX;
public const int NEGATIVE_SUFFIX;
public const int PADDING_CHARACTER;
public const int CURRENCY_CODE;
public const int DEFAULT_RULESET;
public const int PUBLIC_RULESETS;
public const int PERCENT_SYMBOL;
public const int ZERO_DIGIT_SYMBOL;
public const int DIGIT_SYMBOL;
public const int MINUS_SIGN_SYMBOL;
public const int PLUS_SIGN_SYMBOL;
public const int CURRENCY_SYMBOL;
public const int EXPONENTIAL_SYMBOL;
public const int PERMILL_SYMBOL;
public const int PAD_ESCAPE_SYMBOL;
public const int INFINITY_SYMBOL;
public const int NAN_SYMBOL;
public const int TYPE_DEFAULT;
public const int TYPE_INT32;
public const int TYPE_INT64;
public const int TYPE_DOUBLE;
public const int TYPE_CURRENCY;
/* Métodos */
public __construct(string $locale, int $style, ?string $pattern = null)
public static create(string $locale, int $style, ?string $pattern = null): ?NumberFormatter
public format(int|float $num, int $type = NumberFormatter::TYPE_DEFAULT): string|false
public formatCurrency(float $amount, string $currency): string|false
public getAttribute(int $attribute): int|float|false
public getErrorCode(): int
public getSymbol(int $symbol): string|false
public getTextAttribute(int $attribute): string|false
public parse(string $string, int $type = NumberFormatter::TYPE_DOUBLE, int &$offset = null): int|float|false
public parseCurrency(string $string, string &$currency, int &$offset = null): 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
}

Constantes predefinidas

Tipos de Formato

Estes estilos são usados pela função numfmt_create() para definir o tipo do formatador.

NumberFormatter::PATTERN_DECIMAL int
Formato decimal definido por modelo
NumberFormatter::DECIMAL int
Formato decimal
NumberFormatter::CURRENCY int
Formato de moeda
NumberFormatter::PERCENT int
Formato de percentual
NumberFormatter::SCIENTIFIC int
Formato científico
NumberFormatter::SPELLOUT int
Formato baseado em regras ortográficas
NumberFormatter::ORDINAL int
Formato baseado em regras ordinais
NumberFormatter::DURATION int
Formato baseado em regras de duração
NumberFormatter::PATTERN_RULEBASED int
Formato baseado em regras definido por modelo
NumberFormatter::CURRENCY_ACCOUNTING int
Formato de moeda para contabilidade, ex.: ($3.00) para quantidade negativa de moeda ao invés de -$3.00. Disponível a partir do PHP 7.4.1 e ICU 53.
NumberFormatter::DEFAULT_STYLE int
Formato padrão para a localidade
NumberFormatter::IGNORE int
Apelido para PATTERN_DECIMAL

Especificadores de Formatos de Números

Estas constantes definem como os números são analisados ou formatados. Eles devem ser usados como argumentos para as funções numfmt_format() e numfmt_parse().

NumberFormatter::TYPE_DEFAULT int
Deriva o tipo a partir do tipo da variável
NumberFormatter::TYPE_INT32 int
Formata/analisa como um inteiro de 32 bits
NumberFormatter::TYPE_INT64 int
Formata/analisa como um inteiro de 64 bits
NumberFormatter::TYPE_DOUBLE int
Formata/analisa como um valor de ponto flutuante
NumberFormatter::TYPE_CURRENCY int
Formata/analisa como um valor de moeda. Defasado a partir do PHP 8.3.0

Atributos de Formatos de Números

Atributo de formato de número usado pelas funções numfmt_get_attribute() e numfmt_set_attribute().

NumberFormatter::PARSE_INT_ONLY int
Analisa inteiros somente.
NumberFormatter::GROUPING_USED int
Usa separador de agrupamento.
NumberFormatter::DECIMAL_ALWAYS_SHOWN int
Sempre mostra o separador de decimais.
NumberFormatter::MAX_INTEGER_DIGITS int
Máximo de dígitos inteiros.
NumberFormatter::MIN_INTEGER_DIGITS int
Mínimo de dígitos inteiros.
NumberFormatter::INTEGER_DIGITS int
Dígitos inteiros.
NumberFormatter::MAX_FRACTION_DIGITS int
Máximo de dígitos decimais.
NumberFormatter::MIN_FRACTION_DIGITS int
Mínimo de dígitos decimais.
NumberFormatter::FRACTION_DIGITS int
Dígitos decimais.
NumberFormatter::MULTIPLIER int
Multiplicador.
NumberFormatter::GROUPING_SIZE int
Tamanho do agrupamento.
NumberFormatter::ROUNDING_MODE int
Modo de arredondamento.
NumberFormatter::ROUNDING_INCREMENT int
Incremento de arredondamento.
NumberFormatter::FORMAT_WIDTH int
A largura para a qual a saída de format() será preenchida.
NumberFormatter::PADDING_POSITION int
A posição na qual o preenchimento acontecerá. Consulte as constantes de posição de preenchimento para possíveis valores de argumentos.
NumberFormatter::SECONDARY_GROUPING_SIZE int
Tamanho de agrupamento secundário.
NumberFormatter::SIGNIFICANT_DIGITS_USED int
Usa dígitos significativos.
NumberFormatter::MIN_SIGNIFICANT_DIGITS int
Mínimo de dígitos significativos.
NumberFormatter::MAX_SIGNIFICANT_DIGITS int
Máximo de dígitos significativos.
NumberFormatter::LENIENT_PARSE int
Modo de análise brando usado por formatos baseados em regras.

Atributos de Texto de Formatos de Números

Atributo de texto de formato numérico usado por numfmt_get_text_attribute() e numfmt_set_text_attribute().

NumberFormatter::POSITIVE_PREFIX int
Prefixo positivo.
NumberFormatter::POSITIVE_SUFFIX int
Sufixo positivo.
NumberFormatter::NEGATIVE_PREFIX int
Prefixo negativo.
NumberFormatter::NEGATIVE_SUFFIX int
Sufixo negativo.
NumberFormatter::PADDING_CHARACTER int
O caractere usado para preencher a largura do formato.
NumberFormatter::CURRENCY_CODE int
O código de moeda ISO.
NumberFormatter::DEFAULT_RULESET int
O conjunto de regras padrão. Isso está disponível apenas com formatadores baseados em regras.
NumberFormatter::PUBLIC_RULESETS int
Os conjuntos de regras públicas. Isso está disponível apenas com formatadores baseados em regras. Este é um atributo somente leitura. Os conjuntos de regras públicos são retornados como uma única string, com cada nome de conjunto de regras delimitado por ';' (ponto e vírgula).

Especificadores de Formatos de Símbolos

Símbolos de formato de número usados por numfmt_get_symbol() e numfmt_set_symbol().

NumberFormatter::DECIMAL_SEPARATOR_SYMBOL int
O separador de decimais.
NumberFormatter::GROUPING_SEPARATOR_SYMBOL int
O separador de agrupamento.
NumberFormatter::PATTERN_SEPARATOR_SYMBOL int
O separador de padrão.
NumberFormatter::PERCENT_SYMBOL int
O sinal de percentagem.
NumberFormatter::ZERO_DIGIT_SYMBOL int
Zero.
NumberFormatter::DIGIT_SYMBOL int
Caractere representando um dígito no padrão.
NumberFormatter::MINUS_SIGN_SYMBOL int
O sinal de menos.
NumberFormatter::PLUS_SIGN_SYMBOL int
O sinal de mais.
NumberFormatter::CURRENCY_SYMBOL int
O símbolo da moeda.
NumberFormatter::INTL_CURRENCY_SYMBOL int
O símbolo internacional da moeda.
NumberFormatter::MONETARY_SEPARATOR_SYMBOL int
O separador monetário.
NumberFormatter::EXPONENTIAL_SYMBOL int
O símbolo exponencial.
NumberFormatter::PERMILL_SYMBOL int
O símbolo de permilagem.
NumberFormatter::PAD_ESCAPE_SYMBOL int
Caractere de preenchimento de escape.
NumberFormatter::INFINITY_SYMBOL int
Símbolo de infinito.
NumberFormatter::NAN_SYMBOL int
Símbolo representando que o valor não é um número.
NumberFormatter::SIGNIFICANT_DIGIT_SYMBOL int
Símbolo de dígito significativo.
NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL int
O separador de agrupamento monetário.

Modos de Arredondamento

Valores de modo de arredondamento usados por numfmt_get_attribute() e numfmt_set_attribute() com o atributo NumberFormatter::ROUNDING_MODE.

NumberFormatter::ROUND_AWAY_FROM_ZERO
Sinônimo de NumberFormatter::ROUND_UP.
NumberFormatter::ROUND_CEILING int
Modo de arredondamento para arredondar em direção ao infinito positivo.
NumberFormatter::ROUND_DOWN int
Modo de arredondamento para arredondar para zero.
NumberFormatter::ROUND_FLOOR int
Modo de arredondamento para arredondar em direção ao infinito negativo.
NumberFormatter::ROUND_HALFDOWN int
Modo de arredondamento para arredondar para o "vizinho mais próximo", a menos que ambos os vizinhos sejam equidistantes, caso em que arredonda para baixo.
NumberFormatter::ROUND_HALFEVEN int
Modo de arredondamento para arredondar em direção ao "vizinho mais próximo", a menos que ambos os vizinhos sejam equidistantes; nesse caso, arredondar em direção ao vizinho par.
NumberFormatter::ROUND_HALFODD
Modo de arredondamento na direção do "vizinho ímpar".
NumberFormatter::ROUND_HALFUP int
Modo de arredondamento para arredondar para o "vizinho mais próximo", a menos que ambos os vizinhos sejam equidistantes; nesse caso, arredondar para cima.
NumberFormatter::ROUND_TOWARD_ZERO
Sinônimo de NumberFormatter::ROUND_DOWN.
NumberFormatter::ROUND_UP int
Modo de arredondamento para arredondar a partir de zero.

Especificadores de Preenchimento

Valores de posição de preenchimento usados por numfmt_get_attribute() e numfmt_set_attribute() com o atributo NumberFormatter::PADDING_POSITION.

NumberFormatter::PAD_AFTER_PREFIX int
Caracteres de preenchimento inseridos após o prefixo.
NumberFormatter::PAD_AFTER_SUFFIX int
Caracteres de preenchimento inseridos após o sufixo.
NumberFormatter::PAD_BEFORE_PREFIX int
Caracteres de preenchimento inseridos antes do prefixo.
NumberFormatter::PAD_BEFORE_SUFFIX int
Caracteres de preenchimento inseridos antes do sufixo.

Registro de Alterações

Versão Descrição
8.4.0 As constantes de classe agora são tipadas.

Índice

adicione uma nota

Notas Enviadas por Usuários (em inglês) 8 notes

up
49
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
3
jimbo2150 at gmail dot com
1 year ago
The NumberFormatter class can be used to convert integer numbers to Roman numerals without a custom function using an array of symbols and associated values:

<?php

function intToRomanNumeral(int $num) {
static
$nf = new NumberFormatter('@numbers=roman', NumberFormatter::DECIMAL);
return
$nf->format($num);
}

echo
intToRomanNumeral(2); // II

echo intToRomanNumeral(5); // V

echo intToRomanNumeral(10); // X

echo intToRomanNumeral(50); // L

echo intToRomanNumeral(57); // LVII
echo intToRomanNumeral(58); // LVIII

echo intToRomanNumeral(100); // C

echo intToRomanNumeral(150); // CL

echo intToRomanNumeral(1000); // M

echo intToRomanNumeral(10000); // ↂ

?>
up
2
stan at dragnev dot ca
4 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
0
Einenlum
10 months ago
Be aware that (at least with the locale 'fr-FR') NumberFormatter doesn't use spaces. It doesn't even use non breakable spaces (NBSP). It uses narrow non breakable spaces (NNBSP). This broke my tests.

<?php

$formatter
= new NumberFormatter(
'fr-FR',
NumberFormatter::DEFAULT_STYLE
);

$value = $formatter->format(100_000); // '100 000'

// If you want to replace narrow non breakable spaces with non breakable spaces:

str_replace("\u{202F}", "\u{00A0}", $value);

// If you want to replace it with a normal space

str_replace("\u{202F}", " ", $value);
up
2
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
0
gwyneth dot llewelyn at gwynethllewelyn dot net
2 years 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
-2
AF
4 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
-3
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.
To Top