您好,登錄后才能下訂單哦!
小編給大家分享一下PHP中國際化地數字格式處理的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
學習PHP中國際化地數字格式處理
不知道大家有沒有了解過,對于數字格式來說,西方國家會以三位為一個進位,使用逗號來分隔。比如,12345678,用標準的格式來表示的話就是 12,345,678 。不過我們中文其實并不會有這樣的分隔符,另外像某些地區則是以空格為分隔的,這個我們馬上通過代碼就可以看到。其實在之前的文章中我們就已經接觸過一點這方面的知識,學習PHP中的國際化功能來查看貨幣及日期信息,今天就來詳細的學習一遍。至于為什么要格式化數字、貨幣這些內容呢?我們將在文章講解中逐一說明。
數字標準格式
首先還是看我們開頭介紹的標準數字格式。
$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
我們先指定了許多的國家地區編碼,然后循環它們,使用 NumberFormatter 對象來對他們進行實例化。第二個參數就是要實例化的格式類型,這里我們指定的是數字類型。然后使用 format() 方法就可以對指定的數字進行格式化地輸出了。可以看到,德國是使用 . 來分隔進位,使用逗號來做為小數點。而法國和俄羅斯則是使用空格來表示進位,逗號表示小數點。其它國家則是沿用標準的英式表示。
對于很多財務及銀行項目來說,標準數字格式非常有用。往往我們接觸到比較多的是在匯款時要填寫的普通數字、中文大寫,而一些面向企業和涉外的公司財務也需要這種標準格式的數字來進行存根的記錄。既然說到財務了,我們再看看貨幣格式的展示。
貨幣格式
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 р.
在這段代碼中,我們使用了兩種模式的輸出。第一個是指定 NumberFormatter 的第二個參數為 CURRENCY ,也就是指定格式化為貨幣格式。其實就是為標準格式的數字前后增加了對應地區的代幣符號。比如我們中國和日本通用的 ¥ ,一般是放在金額的前面,而歐洲的則使用 € 歐元標識放在金額的后面。
另一種形式就是 formatCurrency() 這個方法可以指定一個貨幣類型,如果不是這個類型的區域設置的話,就直接輸出這個貨幣字符。在測試代碼中,我們給定的是俄羅斯的老盧布,其它區域中會直接輸出 RUR ,而在區域設置為俄羅斯時,輸出的就是標準的老盧布符號(現在使用的是新盧布,符號是 ? ,老盧布就是 р.)。
詳細的地區格式化樣式
是不是感覺已經很高大上了?不不不,上面兩種格式只是開胃菜,真正好玩的現在馬上端給你。
$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; // 一百二十三萬四千五百六十七點八九一二三四五六七九 $fmt = new NumberFormatter('zh_CN', NumberFormatter::SPELLOUT); echo $fmt->format(1234502.891234567890000), PHP_EOL; // 一百二十三萬四千五百〇二點八九一二三四五六七九 $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 不多說了,百分比,就是增加了一個百分號,而且不是以標準格式輸出的,會以空格進行進位分隔。SCIENTIFIC 就是我們常見的科學計數法,測試代碼中的結果就是 1.xx 的 10 的 6 次方的意思。
SPELLOUT 就比較厲害了,按當前區域語言的拼寫規則。沒錯,直接轉換成了我們的中文表示。如果需要再轉換成中文的大寫,直接字符替換就可以了,這個絕對是這次文章的重大發現。之前在一家公司面試的時候就有人問過如何將數字轉換成中文表示,因為很多的財務系統都需要這樣的功能。不管是做帳還是處理發票,中文大寫或小寫都是系統自動輸出的。當時還寫了半天算法,如果大家自己寫算法的時候除了需要注意單位外,零的表示也是非常重要的一點,有興趣的朋友可以自己嘗試一下。不過下回如果面試的時候有人問這個問題,那我直接就會甩出 NumberFormatter::SPELLOUT 這個神器了。
ORDINAL 是排序的表示,在中文中其實就是在前面增加了一個 第 字。DURATION 是基于持續時間規則的格式。這兩種都會拋棄掉小數點。
格式化規則設置
雖說已經有這么多的規則格式供我們使用了,但大家的業務總是千奇百怪的,我們能不能定義自己的格式規則呢?既然這么寫了,那當然是可以的啦。
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() 方法來定義了一個帶 kg 的格式規則,很顯示,我們是需要一個表示重量的格式。然后僅保留一位小數點,不需要分隔符號。這樣再次使用 format() 方法的時候就會按照我們指定的格式來進行格式化了。
屬性操作
當然,除了直接設置規則格式外,我們還可以指定一些屬性值來改變當前的格式效果。
$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() 來設置 MAX_FRACTION_DIGITS 的值,用于改變最大保留的小數點位數。當然,不僅限于這一個屬性,還有很多別的可以修改的屬性,大家可以自行查閱官方手冊。
分隔符號設置
同樣,我們可以直接修改格式化中的分隔符、小數點等使用的符號。直接使用 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
與地區格式化關聯的文本屬性設置
我們還可以直接設置與地區格式化相關的一些文本信息,比如下面代碼中使用 setTextAttribute() 修改了負號的表示。我們還可以使用這個方法修改間隔字符,貨幣編碼等內容,大家可以自己對照官方文檔測試學習。
var_dump($fmt->getTextAttribute(NumberFormatter::NEGATIVE_PREFIX)); // string(1) "-" echo $fmt->format(-1234567.891234567890000), PHP_EOL; $fmt->setTextAttribute(NumberFormatter::NEGATIVE_PREFIX, "負號 "); var_dump($fmt->getTextAttribute(NumberFormatter::NEGATIVE_PREFIX)); // string(7) "負號 " echo $fmt->format(-1234567.891234567890000), PHP_EOL; // 負號 1,234,567.891
獲取地區信息
這兩個方法就是簡單地獲取當前的地區信息了,之前在其它的文章中我們也講過,VALID_LOCALE 是表示有效區域,ACTUAL_LOCALE 表示的是實際區域。
var_dump($fmt->getLocale(Locale::VALID_LOCALE)); // string(10) "zh_Hans_CN" var_dump($fmt->getLocale(Locale::ACTUAL_LOCALE)); // string(10) "zh_Hans_CN"
字符轉換為數字、貨幣格式
我們能夠將數字進行格式化地輸出,輸出之后的內容因為增加了分隔符之類的內容,所以都會轉成字符串,那么,我們能不能把已經格式化過的標準數字字符再轉回數字類型呢?
$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"
兩個方法,第一個是 parse() 方法,將標準格式的數字字符串轉回指定類型的數字,可以指定為 TYPE_INT32 、TYPE_INT64 、TYPE_DOUBLE 、TYPE_CURRENCY 等類型。另外一個方法是 parseCurrency() 方法,從名字就可以看出,它是將貨幣格式轉回數字,并且,很重要的一點是,它的第二個引用參數,可以將貨幣符號的通用編碼也返回回來,比如測試代碼中返回的 CNY 代表的就是我們使用的人民幣。
錯誤信息
最后我們來看看 NumberFormatter 中的錯誤信息如何獲取。
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"
在這里我們使用非標準的貨幣字符串來使用 parseCurrency() 進行轉換,parseCurrency() 必須接收的是帶貨幣符號的內容,所以這里就產生了錯誤。我們使用 getErrorCode() 可以獲取到錯誤碼,使用 getErrorMessage() 可以獲取到錯誤信息。另外是一個 intl_is_failure() 函數,用于根據錯誤碼判斷是否產生了區域語言問題的錯誤。
看完了這篇文章,相信你對“PHP中國際化地數字格式處理的示例分析”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。