SAP UI5 货币金额显示的格式化逻辑

举报
汪子熙 发表于 2022/10/03 10:23:38 2022/10/03
【摘要】 先看一些实际的例子:var oFormat = NumberFormat.getCurrencyInstance({"currencyCode": false, "customCurrencies": {"BTC": {"symbol": "\u0243","decimals": 3}} });oFormat.format(123.4567, "BTC"); // "Ƀ 123.457"上面...

先看一些实际的例子:


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:

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。