SAP UI5 貨幣金額顯示的格式化邏輯

注销發表於2022-02-15

先看一些實際的例子:


var oFormat = NumberFormat.getCurrencyInstance({
"currencyCode": false,
 "customCurrencies": {
"BTC": {
"symbol": "\u0243",
"decimals": 3
}
}
 });

oFormat.format(123.4567, "BTC"); // "Ƀ 123.457"

上面的例子,定義了一個名為 BTC 的自定義貨幣符號,同時用 decimals 指定小數點後的數位,以及貨幣符號的 unicode 編碼值。

執行結果如下:

另一個例子:

var oFormat = NumberFormat.getCurrencyInstance({
     "currencyCode": false,
     "customCurrencies": {
      "MyDollar": {
     "isoCode": "USD",
     "decimals": 3
     },
     "Bitcoin": {
      "decimals": 2
    }
     }
    });

// symbol looked up from global configuration
oFormat.format(123.4567, "MyDollar"); 
// "$123.457"

// no symbol available, custom currency key is rendered
oFormat.format(777.888, "Bitcoin"); // "Bitcoin 777.89"

我們來單步除錯檢視 format 函式的執行原理。

進入 Currency.js 的 formatValue 方法。輸入引數為 87.2 和 EUR:


目標型別為 string 字串,所以進入 case string 的分支:

 */
    Currency.prototype.formatValue = function(vValue, sTargetType) {
        var aValues = vValue;
        if (vValue == undefined || vValue == null) {
            return null;
        }
        if (this.oInputFormat) {
            aValues = this.oInputFormat.parse(vValue);
        }
        if (!Array.isArray(aValues)) {
            throw new FormatException("Cannot format currency: " + vValue + " has the wrong format");
        }
        if ((aValues[0] == undefined || aValues[0] == null) && this.bShowNumber) {
            return null;
        }
        switch (this.getPrimitiveType(sTargetType)) {
            case "string":
                return this.oOutputFormat.format(aValues);
            default:
                throw new FormatException("Don't know how to format currency to " + sTargetType);
        }
    };

讀取 EUR 對應的 digit 數位:

所有的格式都儲存在 LocaleData 裡:

找不到 EUR 對應的 digit 值:

於是讀取 default 配置。如果 default 配置也為空,就返回預設的 2.

default 值維護在此處:2

此處把 87 和 2 使用小數點分隔開,放到不同的變數裡分別儲存:

iDotPos = sNumber.indexOf(".");
        if (iDotPos > -1) {
            sIntegerPart = sNumber.substr(0, iDotPos);
            sFractionPart = sNumber.substr(iDotPos + 1);
        } else {
            sIntegerPart = sNumber;
        }

最終的格式化結果:87.20

看另一個例子:9.99999 EUR

這裡 preserveDecimals 的值為 true,因此 9.99999 小數點後的五個 9,會被保留下來。

如果我們把 preserveDecimals 的值改為 false,

最後顯示的值就四捨五入變成了 10.00:

更多Jerry的原創文章,盡在:"汪子熙":

相關文章