如何在JavaScript中将数字格式设置为美元货币string?
我想用JavaScript格式化一个价格。
我想要一个函数,它将一个float
作为参数,并返回一个格式如下所示的string
:
"$ 2,500.00"
什么是最好的方法来做到这一点?
您可以使用:
var profits=2489.8237 profits.toFixed(3) //returns 2489.824 (round up) profits.toFixed(2) //returns 2489.82 profits.toFixed(7) //returns 2489.8237000 (padding)
然后你可以添加'$'的符号。
如果你需要“,”数千,你可以使用:
Number.prototype.formatMoney = function(c, d, t){ var n = this, c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ? "." : d, t = t == undefined ? "," : t, s = n < 0 ? "-" : "", i = String(parseInt(n = Math.abs(Number(n) || 0).toFixed(c))), j = (j = i.length) > 3 ? j % 3 : 0; return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ""); };
和它一起使用:
(123456789.12345).formatMoney(2, '.', ',');
如果你总是要使用'。' 和',',你可以把它们从方法调用中去掉,方法会默认为你。
(123456789.12345).formatMoney(2);
如果您的文化有两个符号翻转(即欧洲人),只需粘贴在formatMoney
方法的以下两行:
d = d == undefined ? "," : d, t = t == undefined ? "." : t,
简短的解决scheme#1:
n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
简短的解决scheme#2:
n.toFixed(2).replace(/./g, function(c, i, a) { return i && c !== "." && ((a.length - i) % 3 === 0) ? ',' + c : c; });
testing:
1 --> "1.00" 12 --> "12.00" 123 --> "123.00" 1234 --> "1,234.00" 12345 --> "12,345.00" 123456 --> "123,456.00" 1234567 --> "1,234,567.00" 12345.67 --> "12,345.67"
DEMO: http : //jsfiddle.net/hAfMM/
扩展解决scheme
您还可以扩展Number
对象的原型以添加任意小数数[0 .. n]
和数组[0 .. x]
的大小的额外支持:
/** * Number.prototype.format(n, x) * * @param integer n: length of decimal * @param integer x: length of sections */ Number.prototype.format = function(n, x) { var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')'; return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,'); }; 1234..format(); // "1,234" 12345..format(2); // "12,345.00" 123456.7.format(3, 2); // "12,34,56.700" 123456.789.format(2, 4); // "12,3456.79"
演示/testing: http : //jsfiddle.net/hAfMM/435/
超级扩展解决scheme
在这个超级扩展版本中,您可以设置不同的分隔符types:
/** * Number.prototype.format(n, x, s, c) * * @param integer n: length of decimal * @param integer x: length of whole part * @param mixed s: sections delimiter * @param mixed c: decimal delimiter */ Number.prototype.format = function(n, x, s, c) { var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')', num = this.toFixed(Math.max(0, ~~n)); return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ',')); }; 12345678.9.format(2, 3, '.', ','); // "12.345.678,90" 123456.789.format(4, 4, ' ', ':'); // "12 3456:7890" 12345678.9.format(0, 3, '-'); // "12-345-679"
演示/testing: http : //jsfiddle.net/hAfMM/612/
Intl.numberformat
Javascript有一个数字格式化程序,它是国际化API的一部分。
// Create our number formatter. var formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2, // the default value for minimumFractionDigits depends on the currency // and is usually already 2 }); formatter.format(2500); /* $2,500.00 */
JS小提琴
关于浏览器支持的一些说明
- 所有主stream浏览器都支持它
- 一些不太知名的移动浏览器,如UC浏览器和Opera Mini,不支持它
- Mobile v58支持它 (刚刚发布)
- 在旧版浏览器上有一个支持它的选项
- 看看CanIUse的更多信息
Intl.NumberFormat与Number.prototype.toLocaleString
最后一张纸条比较老年人。 toLocaleString
。 它们都提供基本相同的function。 但是,toLocaleString在其旧版本(pre-Intl) 中实际上并不支持语言环境 :它使用系统语言环境。 因此,为确保您使用的是正确版本, MDNbuild议检查是否存在Intl
。 所以如果你需要检查Intl,为什么不使用它呢? 但是,如果您select使用垫片,那也会修补到toLocaleString
,所以在这种情况下您可以毫无麻烦地使用它:
(2500).toLocaleString('en-US', { style: 'currency', currency: 'USD', }); /* $2,500.00 */
下面是Patrick Desjardins(别名Daok)代码,添加了一些注释和一些小的改变:
/* decimal_sep: character used as deciaml separtor, it defaults to '.' when omitted thousands_sep: char used as thousands separator, it defaults to ',' when omitted */ Number.prototype.toMoney = function(decimals, decimal_sep, thousands_sep) { var n = this, c = isNaN(decimals) ? 2 : Math.abs(decimals), //if decimal is zero we must take it, it means user does not want to show any decimal d = decimal_sep || '.', //if no decimal separator is passed we use the dot as default decimal separator (we MUST use a decimal separator) /* according to [https://stackoverflow.com/questions/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function] the fastest way to check for not defined parameter is to use typeof value === 'undefined' rather than doing value === undefined. */ t = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, //if you don't want to use a thousands separator you can pass empty string as thousands_sep value sign = (n < 0) ? '-' : '', //extracting the absolute value of the integer part of the number and converting to string i = parseInt(n = Math.abs(n).toFixed(c)) + '', j = ((j = i.length) > 3) ? j % 3 : 0; return sign + (j ? i.substr(0, j) + t : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ''); }
这里有一些testing:
//some tests (do not forget parenthesis when using negative numbers and number with no decimals) alert(123456789.67392.toMoney() + '\n' + 123456789.67392.toMoney(3) + '\n' + 123456789.67392.toMoney(0) + '\n' + (123456).toMoney() + '\n' + (123456).toMoney(0) + '\n' + 89.67392.toMoney() + '\n' + (89).toMoney()); //some tests (do not forget parenthesis when using negative numbers and number with no decimals) alert((-123456789.67392).toMoney() + '\n' + (-123456789.67392).toMoney(-3));
小的变化是:
-
Math.abs(decimals)
移动了一点,当不是NaN
时才做。 -
decimal_sep
不能再为空string(某种小数分隔符是必须的) -
我们使用
typeof thousands_sep === 'undefined'
按照如何最好地判断一个参数是否没有被发送到JavaScript函数 -
(+n || 0)
不需要,因为this
是一个Number
对象
看看JavaScript的数字对象,看看它是否可以帮助你。
-
toLocaleString()
将使用位置特定的千位分隔符格式化数字。 -
toFixed()
将四舍五入到特定的小数位数。
要同时使用这些值,必须将其types更改回数字,因为它们都输出string。
例:
Number(someNumber.toFixed(1)).toLocaleString()
accounting.js是一个用于数字,货币和货币格式的小型JavaScript库。
这里是我见过的最好的js money格式化器:
Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator) { var n = this, decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces, decSeparator = decSeparator == undefined ? "." : decSeparator, thouSeparator = thouSeparator == undefined ? "," : thouSeparator, sign = n < 0 ? "-" : "", i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) + "", j = (j = i.length) > 3 ? j % 3 : 0; return sign + (j ? i.substr(0, j) + thouSeparator : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : ""); };
它被重新格式化并从这里借用: https : //stackoverflow.com/a/149099/751484
你将不得不提供自己的货币标识符(你使用上面的$)。
像这样调用它(尽pipe注意参数默认为2,逗号和句点,所以如果这是你的偏好,你不需要提供任何参数):
var myMoney=3543.75873; var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
如果金额是一个数字,比如说-123,那么
amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
会产生string“ – $ 123.00”。
这是一个完整的工作示例 。
我想你想要的是f.nettotal.value = "$" + showValue.toFixed(2);
这里已经有一些很好的答案。 这是另一个尝试,只是为了好玩:
function formatDollar(num) { var p = num.toFixed(2).split("."); return "$" + p[0].split("").reverse().reduce(function(acc, num, i, orig) { return num=="-" ? acc : num + (i && !(i % 3) ? "," : "") + acc; }, "") + "." + p[1]; }
还有一些testing:
formatDollar(45664544.23423) // "$45,664,544.23" formatDollar(45) // "$45.00" formatDollar(123) // "$123.00" formatDollar(7824) // "$7,824.00" formatDollar(1) // "$1.00"
编辑:现在它也会处理负数
那么为什么没有人提出以下build议?
(2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2})
适用于大多数/某些浏览器:
好吧,根据你所说的,我使用这个:
var DecimalSeparator = Number("1.2").toLocaleString().substr(1,1); var AmountWithCommas = Amount.toLocaleString(); var arParts = String(AmountWithCommas).split(DecimalSeparator); var intPart = arParts[0]; var decPart = (arParts.length > 1 ? arParts[1] : ''); decPart = (decPart + '00').substr(0,2); return '£ ' + intPart + DecimalSeparator + decPart;
我打开改善build议(我不想包括YUI只是为了做到这一点:-))我已经知道我应该检测到“。 而不是只使用它作为小数点分隔符…
我使用全球化(来自Microsoft)的库: https : //github.com/jquery/globalize
这是一个很好的项目,本地化数字,货币和date,并让他们根据用户区域自动格式化正确的方式! …尽pipe它应该是一个jQuery扩展,它目前是一个100%独立的库。 我build议大家试试看! 🙂
javascript-number-formatter (以前在谷歌代码 )
- 简短,快速,灵活而独立。
只有75行,包括麻省理工学院许可证信息,空白行和评论。 - 接受标准数字格式,如
#,##0.00
或否定-000.####
。 - 接受
#,###.##
# ##0,00
,#,###.##
,#'###.##
或任何types的非编号符号的国家格式。 - 接受任意数量的数字分组。
#,##,#0.000
或#,###0.##
都是有效的。 - 接受任何冗余/防呆格式。
##,###,##.#
或0#,#00#.###0#
都可以。 - 自动编号四舍五入
- 简单的界面,只需提供像这样的掩码和值:
format( "0.0000", 3.141592)
。 - 包含前缀和后缀与掩码
(摘自自述文件)
+1给Jonathan M提供原始方法。 由于这是明确的货币格式化程序,因此我继续向输出添加货币符号(默认为'$'),并将默认逗号添加为千位分隔符。 如果您实际上不需要货币符号(或千位分隔符),只需使用“”(空string)作为您的参数即可。
Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator, currencySymbol) { // check the args and supply defaults: decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces; decSeparator = decSeparator == undefined ? "." : decSeparator; thouSeparator = thouSeparator == undefined ? "," : thouSeparator; currencySymbol = currencySymbol == undefined ? "$" : currencySymbol; var n = this, sign = n < 0 ? "-" : "", i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) + "", j = (j = i.length) > 3 ? j % 3 : 0; return sign + currencySymbol + (j ? i.substr(0, j) + thouSeparator : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : ""); };
Numeral.js – 一个js库,用于通过@adamwdraper轻松进行数字格式化
numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
使用正则expression式的较短方法(用于插入空格,逗号或点)?
Number.prototype.toCurrencyString=function(){ return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 '); } n=12345678.9; alert(n.toCurrencyString());
有一个PHP函数“number_format”的JavaScript端口。
我觉得它非常有用,因为PHP开发人员很容易使用和识别它。
function number_format (number, decimals, dec_point, thousands_sep) { var n = number, prec = decimals; var toFixedFix = function (n,prec) { var k = Math.pow(10,prec); return (Math.round(n*k)/k).toString(); }; n = !isFinite(+n) ? 0 : +n; prec = !isFinite(+prec) ? 0 : Math.abs(prec); var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep; var dec = (typeof dec_point === 'undefined') ? '.' : dec_point; var s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec); //fix for IE parseFloat(0.55).toFixed(0) = 0; var abs = toFixedFix(Math.abs(n), prec); var _, i; if (abs >= 1000) { _ = abs.split(/\D/); i = _[0].length % 3 || 3; _[0] = s.slice(0,i + (n < 0)) + _[0].slice(i).replace(/(\d{3})/g, sep+'$1'); s = _.join(dec); } else { s = s.replace('.', dec); } var decPos = s.indexOf(dec); if (prec >= 1 && decPos !== -1 && (s.length-decPos-1) < prec) { s += new Array(prec-(s.length-decPos-1)).join(0)+'0'; } else if (prec >= 1 && decPos === -1) { s += dec+new Array(prec).join(0)+'0'; } return s; }
(从原来的评论块,包括下面的例子和信贷到期)
// Formats a number with grouped thousands // // version: 906.1806 // discuss at: http://phpjs.org/functions/number_format // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + bugfix by: Michael White (http://getsprink.com) // + bugfix by: Benjamin Lupton // + bugfix by: Allan Jensen (http://www.winternet.no) // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) // + bugfix by: Howard Yeend // + revised by: Luke Smith (http://lucassmith.name) // + bugfix by: Diogo Resende // + bugfix by: Rival // + input by: Kheang Hok Chin (http://www.distantia.ca/) // + improved by: davook // + improved by: Brett Zamir (http://brett-zamir.me) // + input by: Jay Klehr // + improved by: Brett Zamir (http://brett-zamir.me) // + input by: Amir Habibi (http://www.residence-mixte.com/) // + bugfix by: Brett Zamir (http://brett-zamir.me) // * example 1: number_format(1234.56); // * returns 1: '1,235' // * example 2: number_format(1234.56, 2, ',', ' '); // * returns 2: '1 234,56' // * example 3: number_format(1234.5678, 2, '.', ''); // * returns 3: '1234.57' // * example 4: number_format(67, 2, ',', '.'); // * returns 4: '67,00' // * example 5: number_format(1000); // * returns 5: '1,000' // * example 6: number_format(67.311, 2); // * returns 6: '67.31' // * example 7: number_format(1000.55, 1); // * returns 7: '1,000.6' // * example 8: number_format(67000, 5, ',', '.'); // * returns 8: '67.000,00000' // * example 9: number_format(0.9, 0); // * returns 9: '1' // * example 10: number_format('1.20', 2); // * returns 10: '1.20' // * example 11: number_format('1.20', 4); // * returns 11: '1.2000' // * example 12: number_format('1.2000', 3); // * returns 12: '1.200'
帕特里克Desjardins的答案看起来不错,但我更喜欢我的JavaScript简单。 这里有一个函数,我写了一个数字,并以货币forms返回(减去美元符号)
// Format numbers to two decimals with commas function formatDollar(num) { var p = num.toFixed(2).split("."); var chars = p[0].split("").reverse(); var newstr = ''; var count = 0; for (x in chars) { count++; if(count%3 == 1 && count != 1) { newstr = chars[x] + ',' + newstr; } else { newstr = chars[x] + newstr; } } return newstr + "." + p[1]; }
有一个固定在javascript
的内置function
var num = new Number(349); document.write("$" + num.toFixed(2));
我build议Google Visualization API中的NumberFormat类。
你可以做这样的事情:
var formatter = new google.visualization.NumberFormat({ prefix: '$', pattern: '#,###,###.##' }); formatter.formatValue(1000000); // $ 1,000,000
我希望它有帮助。
function CurrencyFormatted(amount) { var i = parseFloat(amount); if(isNaN(i)) { i = 0.00; } var minus = ''; if(i < 0) { minus = '-'; } i = Math.abs(i); i = parseInt((i + .005) * 100); i = i / 100; s = new String(i); if(s.indexOf('.') < 0) { s += '.00'; } if(s.indexOf('.') == (s.length - 2)) { s += '0'; } s = minus + s; return s; }
从WillMaster 。
The main part is inserting the thousand-separators, that could be done like this:
<script type="text/javascript"> function ins1000Sep(val){ val = val.split("."); val[0] = val[0].split("").reverse().join(""); val[0] = val[0].replace(/(\d{3})/g,"$1,"); val[0] = val[0].split("").reverse().join(""); val[0] = val[0].indexOf(",")==0?val[0].substring(1):val[0]; return val.join("."); } function rem1000Sep(val){ return val.replace(/,/g,""); } function formatNum(val){ val = Math.round(val*100)/100; val = (""+val).indexOf(".")>-1 ? val + "00" : val + ".00"; var dec = val.indexOf("."); return dec == val.length-3 || dec == 0 ? val : val.substring(0,dec+3); } </script> <button onclick="alert(ins1000Sep(formatNum(12313231)));">
This might be a little late, but here's a method I just worked up for a coworker to add a locale-aware .toCurrencyString() function to all numbers. The internalization is for number grouping only, NOT the currency sign – if you're outputting dollars, use "$" as supplied, because $123 4567 in Japan or China is the same number of USD as $1,234,567 is here in the US. If you're outputting euro/etc., then change the currency sign from "$".
Declare this anywhere in your HEAD or wherever necessary, just before you need to use it:
Number.prototype.toCurrencyString = function(prefix, suffix) { if (typeof prefix === 'undefined') { prefix = '$'; } if (typeof suffix === 'undefined') { suffix = ''; } var _localeBug = new RegExp((1).toLocaleString().replace(/^1/, '').replace(/\./, '\\.') + "$"); return prefix + (~~this).toLocaleString().replace(_localeBug, '') + (this % 1).toFixed(2).toLocaleString().replace(/^[+-]?0+/,'') + suffix; }
Then you're done! Use (number).toCurrencyString()
anywhere you need to output the number as currency.
var MyNumber = 123456789.125; alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13" MyNumber = -123.567; alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
As usually, there are multiple ways of doing the same thing but I would avoid using Number.prototype.toLocaleString
since it can return different values based on the user settings.
I also don't recommend extending the Number.prototype
– extending native objects prototypes is a bad practice since it can cause conflicts with other people code (eg libraries/frameworks/plugins) and may not be compatible with future JavaScript implementations/versions.
I believe that Regular Expressions are the best approach for the problem, here is my implementation:
/** * Converts number into currency format * @param {number} number Number that should be converted. * @param {string} [decimalSeparator] Decimal separator, defaults to '.'. * @param {string} [thousandsSeparator] Thousands separator, defaults to ','. * @param {int} [nDecimalDigits] Number of decimal digits, defaults to `2`. * @return {string} Formatted string (eg numberToCurrency(12345.67) returns '12,345.67') */ function numberToCurrency(number, decimalSeparator, thousandsSeparator, nDecimalDigits){ //default values decimalSeparator = decimalSeparator || '.'; thousandsSeparator = thousandsSeparator || ','; nDecimalDigits = nDecimalDigits == null? 2 : nDecimalDigits; var fixed = number.toFixed(nDecimalDigits), //limit/add decimal digits parts = new RegExp('^(-?\\d{1,3})((?:\\d{3})+)(\\.(\\d{'+ nDecimalDigits +'}))?$').exec( fixed ); //separate begin [$1], middle [$2] and decimal digits [$4] if(parts){ //number >= 1000 || number <= -1000 return parts[1] + parts[2].replace(/\d{3}/g, thousandsSeparator + '$&') + (parts[4] ? decimalSeparator + parts[4] : ''); }else{ return fixed.replace('.', decimalSeparator); } }
edited on 2010/08/30: added option to set number of decimal digits. edited on 2011/08/23: added option to set number of decimal digits to zero.
这里有一些解决scheme,全部通过testing套件,testing套件和基准包括,如果你想复制和粘贴testing,请试试这个要点 。
方法0(RegExp)
基于https://stackoverflow.com/a/14428340/1877620 ,但修复如果没有小数点。
if (typeof Number.prototype.format === 'undefined') { Number.prototype.format = function (precision) { if (!isFinite(this)) { return this.toString(); } var a = this.toFixed(precision).split('.'); a[0] = a[0].replace(/\d(?=(\d{3})+$)/g, '$&,'); return a.join('.'); } }
方法1
if (typeof Number.prototype.format === 'undefined') { Number.prototype.format = function (precision) { if (!isFinite(this)) { return this.toString(); } var a = this.toFixed(precision).split('.'), // skip the '-' sign head = Number(this < 0); // skip the digits that's before the first thousands separator head += (a[0].length - head) % 3 || 3; a[0] = a[0].slice(0, head) + a[0].slice(head).replace(/\d{3}/g, ',$&'); return a.join('.'); }; }
方法2(拆分到数组)
if (typeof Number.prototype.format === 'undefined') { Number.prototype.format = function (precision) { if (!isFinite(this)) { return this.toString(); } var a = this.toFixed(precision).split('.'); a[0] = a[0] .split('').reverse().join('') .replace(/\d{3}(?=\d)/g, '$&,') .split('').reverse().join(''); return a.join('.'); }; }
方法3(循环)
if (typeof Number.prototype.format === 'undefined') { Number.prototype.format = function (precision) { if (!isFinite(this)) { return this.toString(); } var a = this.toFixed(precision).split(''); a.push('.'); var i = a.indexOf('.') - 3; while (i > 0 && a[i-1] !== '-') { a.splice(i, 0, ','); i -= 3; } a.pop(); return a.join(''); }; }
用法示例
console.log('======== Demo ========') console.log( (1234567).format(0), (1234.56).format(2), (-1234.56).format(0) ); var n = 0; for (var i=1; i<20; i++) { n = (n * 10) + (i % 10)/100; console.log(n.format(2), (-n).format(2)); }
分隔器
If we want custom thousands separator or decimal separator, use replace()
:
123456.78.format(2).replace(',', ' ').replace('.', ' ');
testing套件
function assertEqual(a, b) { if (a !== b) { throw a + ' !== ' + b; } } function test(format_function) { console.log(format_function); assertEqual('NaN', format_function.call(NaN, 0)) assertEqual('Infinity', format_function.call(Infinity, 0)) assertEqual('-Infinity', format_function.call(-Infinity, 0)) assertEqual('0', format_function.call(0, 0)) assertEqual('0.00', format_function.call(0, 2)) assertEqual('1', format_function.call(1, 0)) assertEqual('-1', format_function.call(-1, 0)) // decimal padding assertEqual('1.00', format_function.call(1, 2)) assertEqual('-1.00', format_function.call(-1, 2)) // decimal rounding assertEqual('0.12', format_function.call(0.123456, 2)) assertEqual('0.1235', format_function.call(0.123456, 4)) assertEqual('-0.12', format_function.call(-0.123456, 2)) assertEqual('-0.1235', format_function.call(-0.123456, 4)) // thousands separator assertEqual('1,234', format_function.call(1234.123456, 0)) assertEqual('12,345', format_function.call(12345.123456, 0)) assertEqual('123,456', format_function.call(123456.123456, 0)) assertEqual('1,234,567', format_function.call(1234567.123456, 0)) assertEqual('12,345,678', format_function.call(12345678.123456, 0)) assertEqual('123,456,789', format_function.call(123456789.123456, 0)) assertEqual('-1,234', format_function.call(-1234.123456, 0)) assertEqual('-12,345', format_function.call(-12345.123456, 0)) assertEqual('-123,456', format_function.call(-123456.123456, 0)) assertEqual('-1,234,567', format_function.call(-1234567.123456, 0)) assertEqual('-12,345,678', format_function.call(-12345678.123456, 0)) assertEqual('-123,456,789', format_function.call(-123456789.123456, 0)) // thousands separator and decimal assertEqual('1,234.12', format_function.call(1234.123456, 2)) assertEqual('12,345.12', format_function.call(12345.123456, 2)) assertEqual('123,456.12', format_function.call(123456.123456, 2)) assertEqual('1,234,567.12', format_function.call(1234567.123456, 2)) assertEqual('12,345,678.12', format_function.call(12345678.123456, 2)) assertEqual('123,456,789.12', format_function.call(123456789.123456, 2)) assertEqual('-1,234.12', format_function.call(-1234.123456, 2)) assertEqual('-12,345.12', format_function.call(-12345.123456, 2)) assertEqual('-123,456.12', format_function.call(-123456.123456, 2)) assertEqual('-1,234,567.12', format_function.call(-1234567.123456, 2)) assertEqual('-12,345,678.12', format_function.call(-12345678.123456, 2)) assertEqual('-123,456,789.12', format_function.call(-123456789.123456, 2)) } console.log('======== Testing ========'); test(Number.prototype.format); test(Number.prototype.format1); test(Number.prototype.format2); test(Number.prototype.format3);
基准
function benchmark(f) { var start = new Date().getTime(); f(); return new Date().getTime() - start; } function benchmark_format(f) { console.log(f); time = benchmark(function () { for (var i = 0; i < 100000; i++) { f.call(123456789, 0); f.call(123456789, 2); } }); console.log(time.format(0) + 'ms'); } // if not using async, browser will stop responding while running. // this will create a new thread to benchmark async = []; function next() { setTimeout(function () { f = async.shift(); f && f(); next(); }, 10); } console.log('======== Benchmark ========'); async.push(function () { benchmark_format(Number.prototype.format); }); next();
Haven't seen this one. It's pretty concise and easy to understand.
function moneyFormat(price, sign = '$') { const pieces = parseFloat(price).toFixed(2).split('') let ii = pieces.length - 3 while ((ii-=3) > 0) { pieces.splice(ii, 0, ',') } return sign + pieces.join('') } console.log( moneyFormat(100), moneyFormat(1000), moneyFormat(10000.00), moneyFormat(1000000000000000000) )
A simple option for proper comma placement by reversing the string first and basic regexp.
String.prototype.reverse = function() { return this.split('').reverse().join(''); }; Number.prototype.toCurrency = function( round_decimal /*boolean*/ ) { // format decimal or round to nearest integer var n = this.toFixed( round_decimal ? 0 : 2 ); // convert to a string, add commas every 3 digits from left to right // by reversing string return (n + '').reverse().replace( /(\d{3})(?=\d)/g, '$1,' ).reverse(); };
Patrick Desjardins (ex Daok)'s example worked well for me. I ported over to coffeescript if anyone is interested.
Number.prototype.toMoney = (decimals = 2, decimal_separator = ".", thousands_separator = ",") -> n = this c = if isNaN(decimals) then 2 else Math.abs decimals sign = if n < 0 then "-" else "" i = parseInt(n = Math.abs(n).toFixed(c)) + '' j = if (j = i.length) > 3 then j % 3 else 0 x = if j then i.substr(0, j) + thousands_separator else '' y = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_separator) z = if c then decimal_separator + Math.abs(n - i).toFixed(c).slice(2) else '' sign + x + y + z
I found this from: accounting.js . Its very easy and perfectly fits my need.
// Default usage: accounting.formatMoney(12345678); // $12,345,678.00 // European formatting (custom symbol and separators), can also use options object as second parameter: accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99 // Negative values can be formatted nicely: accounting.formatMoney(-500000, "£ ", 0); // £ -500,000 // Simple `format` string allows control of symbol position (%v = value, %s = symbol): accounting.formatMoney(5318008, { symbol: "GBP", format: "%v %s" }); // 5,318,008.00 GBP // Euro currency symbol to the right accounting.formatMoney(5318008, {symbol: "€", precision: 2, thousand: ".", decimal : ",", format: "%v%s"}); // 1.008,00€