NumberFormatter クラス

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

はじめに

プログラムで数値を保存したり操作したりする際には、 ロケールに依存しないバイナリ表現を使用します。 数値を表示するときに、ロケールにあわせた文字列形式に変換します。 たとえば 12345.67 という数値の表記はアメリカでは "12,345.67"、 フランスでは "12 345,67"、そしてドイツでは "12.345,67" となります。

NumberFormatter クラスのメソッドを実行すると、 数値や通貨、パーセンテージなどの値をロケールに応じた形式にフォーマットすることができます。 NumberFormatter はロケールを考慮した処理を行うので、 ロケールごとに別の NumberFormatter を用意する必要があります。 NumberFormatter のメソッドは、浮動小数点数値のような数値を ロケールにあわせた文字列に変換します。

通貨の場合は、通貨用の書式を使用してフォーマッタを作成します。 これは、ロケールにあわせて数値を適切な書式にして通貨記号をつけた文字列を返します。 もちろん、NumberFormatter クラスは為替レートの変換などは考慮しません。 指定した通貨にかかわらず、出力される数値は同じものとなります。 つまり、ロケールによって同じ数値が違う額を表すことになるということです。 9988776.65 という数値を指定したときの結果は次のようになります。

  • 9 988 776,65 € (フランス)
  • 9.988.776,65 € (ドイツ)
  • $9,988,776.65 in (アメリカ)

パーセンテージをフォーマットするには、 パーセンテージ用の書式を指定したフォーマッタを作成します。 これを使用すると、たとえば 0.75 のような小数が 75% と表示されるようになります。

spelled-out numbers のような複雑な書式を設定する場合は、 ルールベースの数値フォーマッタを使用します。

クラス概要

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)
浮動小数点数値としてフォーマット/パースする
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)
ルールベースのフォーマットで使用する Lenient パースモード

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)
国際通貨記号
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)
非数値記号
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