溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

PHP中國(guó)際化地?cái)?shù)字格式處理的示例分析

發(fā)布時(shí)間:2021-07-02 14:23:49 來源:億速云 閱讀:102 作者:小新 欄目:編程語(yǔ)言

小編給大家分享一下PHP中國(guó)際化地?cái)?shù)字格式處理的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

學(xué)習(xí)PHP中國(guó)際化地?cái)?shù)字格式處理

不知道大家有沒有了解過,對(duì)于數(shù)字格式來說,西方國(guó)家會(huì)以三位為一個(gè)進(jìn)位,使用逗號(hào)來分隔。比如,12345678,用標(biāo)準(zhǔn)的格式來表示的話就是 12,345,678 。不過我們中文其實(shí)并不會(huì)有這樣的分隔符,另外像某些地區(qū)則是以空格為分隔的,這個(gè)我們馬上通過代碼就可以看到。其實(shí)在之前的文章中我們就已經(jīng)接觸過一點(diǎn)這方面的知識(shí),學(xué)習(xí)PHP中的國(guó)際化功能來查看貨幣及日期信息,今天就來詳細(xì)的學(xué)習(xí)一遍。至于為什么要格式化數(shù)字、貨幣這些內(nèi)容呢?我們將在文章講解中逐一說明。

數(shù)字標(biāo)準(zhǔn)格式

首先還是看我們開頭介紹的標(biāo)準(zhǔn)數(shù)字格式。

$localeArr = ['en_US', 'zh_CN', 'ja_JP', 'de_DE', 'fr_FR', 'ar-IQ', 'ru_RU'];
foreach ($localeArr as $locale) {
    $fmt = new NumberFormatter($locale, NumberFormatter::DECIMAL);
    echo $locale . ':', $fmt->format(1234567.891234567890000), PHP_EOL;
}
// en_US:1,234,567.891
// zh_CN:1,234,567.891
// ja_JP:1,234,567.891
// de_DE:1.234.567,891
// fr_FR:1 234 567,891
// ar-IQ:?????????????
// ru_RU:1 234 567,891

我們先指定了許多的國(guó)家地區(qū)編碼,然后循環(huán)它們,使用 NumberFormatter 對(duì)象來對(duì)他們進(jìn)行實(shí)例化。第二個(gè)參數(shù)就是要實(shí)例化的格式類型,這里我們指定的是數(shù)字類型。然后使用 format() 方法就可以對(duì)指定的數(shù)字進(jìn)行格式化地輸出了。可以看到,德國(guó)是使用 . 來分隔進(jìn)位,使用逗號(hào)來做為小數(shù)點(diǎn)。而法國(guó)和俄羅斯則是使用空格來表示進(jìn)位,逗號(hào)表示小數(shù)點(diǎn)。其它國(guó)家則是沿用標(biāo)準(zhǔn)的英式表示。

對(duì)于很多財(cái)務(wù)及銀行項(xiàng)目來說,標(biāo)準(zhǔn)數(shù)字格式非常有用。往往我們接觸到比較多的是在匯款時(shí)要填寫的普通數(shù)字、中文大寫,而一些面向企業(yè)和涉外的公司財(cái)務(wù)也需要這種標(biāo)準(zhǔn)格式的數(shù)字來進(jìn)行存根的記錄。既然說到財(cái)務(wù)了,我們?cè)倏纯簇泿鸥袷降恼故尽?/p>

貨幣格式

foreach ($localeArr as $locale) {
    $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
    echo $locale . ':', $fmt->format(1234567.891234567890000), PHP_EOL;
    echo $locale . ':', $fmt->formatCurrency(1234567.891234567890000, 'RUR'), PHP_EOL;
}
// en_US:$1,234,567.89
// en_US:RUR 1,234,567.89
// zh_CN:¥1,234,567.89
// zh_CN:RUR 1,234,567.89
// ja_JP:¥1,234,568
// ja_JP:RUR 1,234,567.89
// de_DE:1.234.567,89 €
// de_DE:1.234.567,89 RUR
// fr_FR:1 234 567,89 €
// fr_FR:1 234 567,89 RUR
// ar-IQ:????????? ?.?.?
// ar-IQ:???????????? RUR
// ru_RU:1 234 567,89 ?
// ru_RU:1 234 567,89 р.

在這段代碼中,我們使用了兩種模式的輸出。第一個(gè)是指定 NumberFormatter 的第二個(gè)參數(shù)為 CURRENCY ,也就是指定格式化為貨幣格式。其實(shí)就是為標(biāo)準(zhǔn)格式的數(shù)字前后增加了對(duì)應(yīng)地區(qū)的代幣符號(hào)。比如我們中國(guó)和日本通用的 ¥ ,一般是放在金額的前面,而歐洲的則使用 € 歐元標(biāo)識(shí)放在金額的后面。

另一種形式就是 formatCurrency() 這個(gè)方法可以指定一個(gè)貨幣類型,如果不是這個(gè)類型的區(qū)域設(shè)置的話,就直接輸出這個(gè)貨幣字符。在測(cè)試代碼中,我們給定的是俄羅斯的老盧布,其它區(qū)域中會(huì)直接輸出 RUR ,而在區(qū)域設(shè)置為俄羅斯時(shí),輸出的就是標(biāo)準(zhǔn)的老盧布符號(hào)(現(xiàn)在使用的是新盧布,符號(hào)是 ? ,老盧布就是 р.)。

詳細(xì)的地區(qū)格式化樣式

是不是感覺已經(jīng)很高大上了?不不不,上面兩種格式只是開胃菜,真正好玩的現(xiàn)在馬上端給你。

$fmt = new NumberFormatter('zh_CN', NumberFormatter::PERCENT);
echo $fmt->format(1234567.891234567890000), PHP_EOL; // 123 456 789 %
$fmt = new NumberFormatter('zh_CN', NumberFormatter::SCIENTIFIC);
echo $fmt->format(1234567.891234567890000), PHP_EOL; // 1,2345678912345679E6
$fmt = new NumberFormatter('zh_CN', NumberFormatter::SPELLOUT);
echo $fmt->format(1234567.891234567890000), PHP_EOL; // 一百二十三萬(wàn)四千五百六十七點(diǎn)八九一二三四五六七九
$fmt = new NumberFormatter('zh_CN', NumberFormatter::SPELLOUT);
echo $fmt->format(1234502.891234567890000), PHP_EOL; // 一百二十三萬(wàn)四千五百〇二點(diǎn)八九一二三四五六七九
$fmt = new NumberFormatter('zh_CN', NumberFormatter::ORDINAL);
echo $fmt->format(1234567.891234567890000), PHP_EOL; // 第1,234,568
$fmt = new NumberFormatter('zh_CN', NumberFormatter::DURATION);
echo $fmt->format(1234567.891234567890000), PHP_EOL; // 1,234,568

PERCENT 不多說了,百分比,就是增加了一個(gè)百分號(hào),而且不是以標(biāo)準(zhǔn)格式輸出的,會(huì)以空格進(jìn)行進(jìn)位分隔。SCIENTIFIC 就是我們常見的科學(xué)計(jì)數(shù)法,測(cè)試代碼中的結(jié)果就是 1.xx 的 10 的 6 次方的意思。

SPELLOUT 就比較厲害了,按當(dāng)前區(qū)域語(yǔ)言的拼寫規(guī)則。沒錯(cuò),直接轉(zhuǎn)換成了我們的中文表示。如果需要再轉(zhuǎn)換成中文的大寫,直接字符替換就可以了,這個(gè)絕對(duì)是這次文章的重大發(fā)現(xiàn)。之前在一家公司面試的時(shí)候就有人問過如何將數(shù)字轉(zhuǎn)換成中文表示,因?yàn)楹芏嗟呢?cái)務(wù)系統(tǒng)都需要這樣的功能。不管是做帳還是處理發(fā)票,中文大寫或小寫都是系統(tǒng)自動(dòng)輸出的。當(dāng)時(shí)還寫了半天算法,如果大家自己寫算法的時(shí)候除了需要注意單位外,零的表示也是非常重要的一點(diǎn),有興趣的朋友可以自己嘗試一下。不過下回如果面試的時(shí)候有人問這個(gè)問題,那我直接就會(huì)甩出 NumberFormatter::SPELLOUT 這個(gè)神器了。

ORDINAL 是排序的表示,在中文中其實(shí)就是在前面增加了一個(gè) 第 字。DURATION 是基于持續(xù)時(shí)間規(guī)則的格式。這兩種都會(huì)拋棄掉小數(shù)點(diǎn)。

格式化規(guī)則設(shè)置

雖說已經(jīng)有這么多的規(guī)則格式供我們使用了,但大家的業(yè)務(wù)總是千奇百怪的,我們能不能定義自己的格式規(guī)則呢?既然這么寫了,那當(dāng)然是可以的啦。

var_dump($fmt->getPattern()); // string(8) "#,##0.##"
$fmt->setPattern("#0.# kg");
var_dump($fmt->getPattern()); // string(6) "0.# kg"
echo $fmt->format(1234567.891234567890000), PHP_EOL; // 1234567.9 kg

看出來了嗎?我們使用 setPattern() 方法來定義了一個(gè)帶 kg 的格式規(guī)則,很顯示,我們是需要一個(gè)表示重量的格式。然后僅保留一位小數(shù)點(diǎn),不需要分隔符號(hào)。這樣再次使用 format() 方法的時(shí)候就會(huì)按照我們指定的格式來進(jìn)行格式化了。

屬性操作

當(dāng)然,除了直接設(shè)置規(guī)則格式外,我們還可以指定一些屬性值來改變當(dāng)前的格式效果。

$fmt = new NumberFormatter( 'zh_CN', NumberFormatter::DECIMAL );
echo "Digits: ".$fmt->getAttribute(NumberFormatter::MAX_FRACTION_DIGITS), PHP_EOL; // Digits: 3
echo $fmt->format(1234567.891234567890000), PHP_EOL; // 1,234,567.891
$fmt->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 2);
echo "Digits: ".$fmt->getAttribute(NumberFormatter::MAX_FRACTION_DIGITS), PHP_EOL; // Digits: 2
echo $fmt->format(1234567.891234567890000), PHP_EOL; // 1,234,567.89

這段代碼中,我們通過 setAttribute() 來設(shè)置 MAX_FRACTION_DIGITS 的值,用于改變最大保留的小數(shù)點(diǎn)位數(shù)。當(dāng)然,不僅限于這一個(gè)屬性,還有很多別的可以修改的屬性,大家可以自行查閱官方手冊(cè)。

分隔符號(hào)設(shè)置

同樣,我們可以直接修改格式化中的分隔符、小數(shù)點(diǎn)等使用的符號(hào)。直接使用 setSymbol() 方法就可以。

var_dump($fmt->getSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL)); // string(1) ","
$fmt->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, "*");
var_dump($fmt->getSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL)); // string(1) "*"
echo $fmt->format(1234567.891234567890000), PHP_EOL; // 1*234*567.891

與地區(qū)格式化關(guān)聯(lián)的文本屬性設(shè)置

我們還可以直接設(shè)置與地區(qū)格式化相關(guān)的一些文本信息,比如下面代碼中使用 setTextAttribute() 修改了負(fù)號(hào)的表示。我們還可以使用這個(gè)方法修改間隔字符,貨幣編碼等內(nèi)容,大家可以自己對(duì)照官方文檔測(cè)試學(xué)習(xí)。

var_dump($fmt->getTextAttribute(NumberFormatter::NEGATIVE_PREFIX)); // string(1) "-"
echo $fmt->format(-1234567.891234567890000), PHP_EOL;
$fmt->setTextAttribute(NumberFormatter::NEGATIVE_PREFIX, "負(fù)號(hào) ");
var_dump($fmt->getTextAttribute(NumberFormatter::NEGATIVE_PREFIX)); // string(7) "負(fù)號(hào) "
echo $fmt->format(-1234567.891234567890000), PHP_EOL; // 負(fù)號(hào) 1,234,567.891

獲取地區(qū)信息

這兩個(gè)方法就是簡(jiǎn)單地獲取當(dāng)前的地區(qū)信息了,之前在其它的文章中我們也講過,VALID_LOCALE 是表示有效區(qū)域,ACTUAL_LOCALE 表示的是實(shí)際區(qū)域。

var_dump($fmt->getLocale(Locale::VALID_LOCALE)); // string(10) "zh_Hans_CN"
var_dump($fmt->getLocale(Locale::ACTUAL_LOCALE)); // string(10) "zh_Hans_CN"

字符轉(zhuǎn)換為數(shù)字、貨幣格式

我們能夠?qū)?shù)字進(jìn)行格式化地輸出,輸出之后的內(nèi)容因?yàn)樵黾恿朔指舴惖膬?nèi)容,所以都會(huì)轉(zhuǎn)成字符串,那么,我們能不能把已經(jīng)格式化過的標(biāo)準(zhǔn)數(shù)字字符再轉(zhuǎn)回?cái)?shù)字類型呢?

$fmt = new NumberFormatter( 'zh_CN', NumberFormatter::DECIMAL );
$num = "1,234,567.891";
echo $fmt->parse($num)."\n"; // 1234567.891
echo $fmt->parse($num, NumberFormatter::TYPE_INT32)."\n"; // 1234567
$fmt = new NumberFormatter( 'zh_CN', NumberFormatter::CURRENCY );
echo $fmt->parseCurrency('¥1,234,567.89', $currency), PHP_EOL; // 1234567.89
var_dump($currency); // string(3) "CNY"

兩個(gè)方法,第一個(gè)是 parse() 方法,將標(biāo)準(zhǔn)格式的數(shù)字字符串轉(zhuǎn)回指定類型的數(shù)字,可以指定為 TYPE_INT32 、TYPE_INT64 、TYPE_DOUBLE 、TYPE_CURRENCY 等類型。另外一個(gè)方法是 parseCurrency() 方法,從名字就可以看出,它是將貨幣格式轉(zhuǎn)回?cái)?shù)字,并且,很重要的一點(diǎn)是,它的第二個(gè)引用參數(shù),可以將貨幣符號(hào)的通用編碼也返回回來,比如測(cè)試代碼中返回的 CNY 代表的就是我們使用的人民幣。

錯(cuò)誤信息

最后我們來看看 NumberFormatter 中的錯(cuò)誤信息如何獲取。

echo $fmt->parseCurrency('1,234,567.89', $currency), PHP_EOL;
var_dump($fmt->getErrorCode()); // int(9)
var_dump(intl_is_failure($fmt->getErrorCode())); // bool(true)
var_dump($fmt->getErrorMessage()); // string(36) "Number parsing failed: U_PARSE_ERROR"

在這里我們使用非標(biāo)準(zhǔn)的貨幣字符串來使用 parseCurrency() 進(jìn)行轉(zhuǎn)換,parseCurrency() 必須接收的是帶貨幣符號(hào)的內(nèi)容,所以這里就產(chǎn)生了錯(cuò)誤。我們使用 getErrorCode() 可以獲取到錯(cuò)誤碼,使用 getErrorMessage() 可以獲取到錯(cuò)誤信息。另外是一個(gè) intl_is_failure() 函數(shù),用于根據(jù)錯(cuò)誤碼判斷是否產(chǎn)生了區(qū)域語(yǔ)言問題的錯(cuò)誤。

看完了這篇文章,相信你對(duì)“PHP中國(guó)際化地?cái)?shù)字格式處理的示例分析”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI