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 类提供的 method,您可以根据指定的或默认语言环境格式化数字、货币和百分比。NumberFormatter 对语言环境敏感,因此您需要为每个语言环境创建一个新的 NumberFormatter。NumberFormatter method 格式化基本类型的数字,例如 double,并将数字输出为特定于语言环境的字符串。

对于货币,您可以使用货币格式类型创建返回格式化数字和适当货币符号的格式化器。当然,NumberFormatter 类不知道汇率,因此无论指定哪种货币,输出的数字都是一样的。这意味着同一个数字在不同的货币语言环境中具有不同的货币价值。如果数字是 9988776.65,结果将是

  • 在法国,9 988 776,65 €
  • 在德国,9.988.776,65 €
  • 在美国,$9,988,776.65

为了格式化百分比,请使用百分比格式类型创建特定于语言环境的格式化器。使用此格式化器,十进制小数,例如 0.75,将显示为 75%。

对于更复杂的格式化,例如拼写数字,使用基于规则的数字格式化器。

类概要

class NumberFormatter {
/* 常量 */
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_HALFEVEN;
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;
/* Methods */
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
}

预定义常量

格式类型

这些样式由 numfmt_create() 用于定义格式化程序的类型。

NumberFormatter::PATTERN_DECIMAL
由模式定义的十进制格式
NumberFormatter::DECIMAL
十进制格式
NumberFormatter::CURRENCY
货币格式
NumberFormatter::PERCENT
百分比格式
NumberFormatter::SCIENTIFIC
科学记数法格式
NumberFormatter::SPELLOUT
拼写规则格式
NumberFormatter::ORDINAL
序数规则格式
NumberFormatter::DURATION
持续时间规则格式
NumberFormatter::PATTERN_RULEBASED
由模式定义的基于规则的格式
NumberFormatter::CURRENCY_ACCOUNTING
用于会计的货币格式,例如,对于负货币金额,使用 ($3.00) 而不是 -$3.00。 从 PHP 7.4.1 和 ICU 53 开始可用。
NumberFormatter::DEFAULT_STYLE
区域设置的默认格式
NumberFormatter::IGNORE
PATTERN_DECIMAL 的别名

数字格式说明符

这些常量定义了如何解析或格式化数字。 它们应该用作 numfmt_format()numfmt_parse() 的参数。

NumberFormatter::TYPE_DEFAULT
从变量类型推断类型
NumberFormatter::TYPE_INT32
格式化/解析为 32 位整数
NumberFormatter::TYPE_INT64
格式化/解析为 64 位整数
NumberFormatter::TYPE_DOUBLE
格式化/解析为浮点值
NumberFormatter::TYPE_CURRENCY
格式化/解析为货币值。 从 PHP 8.3.0 开始弃用

数字格式属性

数字格式属性,由 numfmt_get_attribute()numfmt_set_attribute() 使用。

NumberFormatter::PARSE_INT_ONLY
仅解析整数。
NumberFormatter::GROUPING_USED
使用分组分隔符。
NumberFormatter::DECIMAL_ALWAYS_SHOWN
始终显示小数点。
NumberFormatter::MAX_INTEGER_DIGITS
最大整数位数。
NumberFormatter::MIN_INTEGER_DIGITS
最小整数位数。
NumberFormatter::INTEGER_DIGITS
整数位数。
NumberFormatter::MAX_FRACTION_DIGITS
最大小数位数。
NumberFormatter::MIN_FRACTION_DIGITS
最小小数位数。
NumberFormatter::FRACTION_DIGITS
小数位数。
NumberFormatter::MULTIPLIER
乘数。
NumberFormatter::GROUPING_SIZE
分组大小。
NumberFormatter::ROUNDING_MODE
舍入模式。
NumberFormatter::ROUNDING_INCREMENT
舍入增量。
NumberFormatter::FORMAT_WIDTH
format() 输出的填充宽度。
NumberFormatter::PADDING_POSITION
填充将发生的方位。 请参阅填充位置常量以获取可能的参数值。
NumberFormatter::SECONDARY_GROUPING_SIZE
次要分组大小。
NumberFormatter::SIGNIFICANT_DIGITS_USED
使用有效数字。
NumberFormatter::MIN_SIGNIFICANT_DIGITS
最小有效数字。
NumberFormatter::MAX_SIGNIFICANT_DIGITS
最大有效数字。
NumberFormatter::LENIENT_PARSE
基于规则的格式使用的宽松解析模式。

数字格式文本属性

数字格式文本属性,由 numfmt_get_text_attribute()numfmt_set_text_attribute() 使用。

NumberFormatter::POSITIVE_PREFIX
正前缀。
NumberFormatter::POSITIVE_SUFFIX
正后缀。
NumberFormatter::NEGATIVE_PREFIX
负前缀。
NumberFormatter::NEGATIVE_SUFFIX
负后缀。
NumberFormatter::PADDING_CHARACTER
用于填充到格式宽度的字符。
NumberFormatter::CURRENCY_CODE
ISO 货币代码。
NumberFormatter::DEFAULT_RULESET
默认规则集。 这只对基于规则的格式化程序可用。
NumberFormatter::PUBLIC_RULESETS
公共规则集。 这只对基于规则的格式化程序可用。 这是一个只读属性。 公共规则集将作为一个字符串返回,每个规则集名称由“;” (分号) 分隔。

舍入模式

舍入模式值,由 numfmt_get_attribute()numfmt_set_attribute()NumberFormatter::ROUNDING_MODE 属性一起使用。

NumberFormatter::ROUND_CEILING
舍入模式,向上舍入到正无穷大。
NumberFormatter::ROUND_DOWN
舍入模式,向零舍入。
NumberFormatter::ROUND_FLOOR
舍入模式,向下舍入到负无穷大。
NumberFormatter::ROUND_HALFDOWN
舍入模式,舍入到“最近的邻居”,除非两个邻居距离相等,在这种情况下向下舍入。
NumberFormatter::ROUND_HALFEVEN
舍入模式,舍入到“最近的邻居”,除非两个邻居距离相等,在这种情况下,舍入到偶数邻居。
NumberFormatter::ROUND_HALFUP
舍入模式,舍入到“最近的邻居”,除非两个邻居距离相等,在这种情况下向上舍入。
NumberFormatter::ROUND_UP
舍入模式,远离零舍入。

填充说明符

填充位置值,由 numfmt_get_attribute()numfmt_set_attribute()NumberFormatter::PADDING_POSITION 属性一起使用。

NumberFormatter::PAD_AFTER_PREFIX
在后缀后插入填充字符。
NumberFormatter::PAD_AFTER_SUFFIX
在后缀后插入填充字符。
NumberFormatter::PAD_BEFORE_PREFIX
在后缀前插入填充字符。
NumberFormatter::PAD_BEFORE_SUFFIX
在后缀前插入填充字符。

目录

添加注释

用户贡献的注释 9 个注释

giorgio dot liscio at email dot it
13 年前
这个类看起来很痛苦:实际上并非如此,格式化和解析高度可定制,但你可能需要的是非常简单的

如果你想本地化一个数字,请使用

<?php
$a
= new \NumberFormatter("it-IT", \NumberFormatter::DECIMAL);
echo
$a->format(12345.12345) . "<br>"; // 输出 12.345,12
$a->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, 0);
$a->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 100); // 默认情况下,一些语言环境最多有 2 位小数位,这可能不是你想要的
echo $a->format(12345.12345) . "<br>"; // 输出 12.345,12345
?>

如果你想打印货币,请使用

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

如果你有以(例如)美元存储的货币数据,并且想使用 it-IT 符号打印它们,你需要使用

<?php
$a
= new \NumberFormatter("it-IT", \NumberFormatter::CURRENCY);
echo
$a->formatCurrency(12345, "USD") . "<br>"; // 输出 $ 12.345,00 并且它使用意大利符号进行格式化(逗号作为小数分隔符)
?>

关于货币的另一个有用示例(如何从语言环境字符串获取货币名称)

<?php
$frontEndFormatter
= new \NumberFormatter("it-IT", \NumberFormatter::CURRENCY);
$adminFormatter = new \NumberFormatter("en-US", \NumberFormatter::CURRENCY);
$symbol = $adminFormatter->getSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL); // 获取 USD
echo $frontEndFormatter->formatCurrency(12345.12345, $symbol) . "<br>";
?>
jimbo2150 at gmail dot com
1 年前
NumberFormatter 类可以用来将整数转换为罗马数字,而无需使用符号数组和关联值的自定义函数

<?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); // ↂ

?>
stan at dragnev dot ca
3 年前
以下是如何使用 PATTERN_DECIMAL 打印带有两位小数位的数字的示例,使用 () 表示负数,并使用空格作为填充字符,在小数点左侧填充到五个字符

<?php

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

// 输出:" (45.10)"

?>

请注意,模式中的分号表示子模式的开始,子模式用于负数。因此,分号后的模式用括号括起来。
Einenlum
6 个月前
请注意,(至少对于语言环境“fr-FR”)NumberFormatter 不使用空格。它甚至不使用不间断空格 (NBSP)。它使用窄不间断空格 (NNBSP)。这破坏了我的测试。

<?php

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

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

// 如果你想用不间断空格替换窄不间断空格:

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

// 如果你想用普通空格替换它

str_replace("\u{202F}", " ", $value);
gwyneth dot llewelyn at gwynethllewelyn dot net
2 年前
当在 PHP 7.3 和 8+ 中使用 `NumberFormatter` 类进行漂亮的货币打印时,文档中没有明确说明你可以使用空字符串 "" 作为构造函数的语言环境,这将检索默认语言环境(无论它在你的环境中设置为哪个)。

`formatCurrency()` 相反,不接受空字符串作为默认货币符号;它将显示一个“通用”货币符号(¤)。

在 Ubuntu Linux 下的 PHP 7.4.30、8.0.21、8.1.8 和 macOS Big Sur (11.6.8) 下的 8.1.8 中进行了测试。我尝试了其他替代方案(例如在 ARM 芯片上运行的 Linux,PHP 7.3.3),但遗憾的是,`NumberFormatter` 库似乎不存在(或者找不到)这些系统上…
sudheer at binaryvibes dot co dot in
13 年前
用于以英文打印数字的示例脚本。

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

?>

生成的结果
one hundred twenty-three thousand four hundred fifty-six
AF
3 年前
请注意阿拉伯小数分隔符 (https://en.wikipedia.org/wiki/Decimal_separator#Other_numeral_systems).

以下所有条件都为真
<?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) != ',';
?>
Joey
7 年前
请注意,此类有时缺乏足够的错误输出。我最近在构造函数中使用无效模式实例化了它。

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

致命错误:调用未定义方法 format() on null in 命令行代码 on line 1

在调用 new 之后返回 null,而不是发出错误消息或抛出异常。

我不确定 PHP 7 中是否已修复,但这需要注意。请确保您非常仔细地检查参数。
Adam
7 年前
很高兴知道 Numberformatter::SPELLOUT 使用软连字符。

因此,如果您想避免它,请使用 preg_replace

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

使用 preg_replace 的输出
egyszázhuszonháromezer négyszázötvenhat
To Top