我想用JavaScript格式化价格.
我想要一个函数,它接受一个float
参数并返回如下string
格式:
"$ 2,500.00"
最好的方法是什么?
此解决方案与每个主要浏览器兼容:
const profits = 2489.8237; profits.toFixed(3) //returns 2489.824 (rounds up) profits.toFixed(2) //returns 2489.82 profits.toFixed(7) //returns 2489.8237000 (pads the decimals)
您只需要添加货币符号(例如"$" + profits.toFixed(2)
),您将获得美元金额.
如果您需要,
在每个数字之间使用,您可以使用此功能:
function formatMoney(number, decPlaces, decSep, thouSep) {
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
decSep = typeof decSep === "undefined" ? "." : decSep;
thouSep = typeof thouSep === "undefined" ? "," : thouSep;
var sign = number < 0 ? "-" : "";
var i = String(parseInt(number = Math.abs(Number(number) || 0).toFixed(decPlaces)));
var j = (j = i.length) > 3 ? j % 3 : 0;
return sign +
(j ? i.substr(0, j) + thouSep : "") +
i.substr(j).replace(/(\decSep{3})(?=\decSep)/g, "$1" + thouSep) +
(decPlaces ? decSep + Math.abs(number - i).toFixed(decPlaces).slice(2) : "");
}
document.getElementById("b").addEventListener("click", event => {
document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
(press button to get output)
(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); // 12,345.67
这个解决方案背后的想法是用第一个匹配和逗号替换匹配的部分,即'$&,'
.匹配是使用先行方法完成的.您可以将表达式读作"匹配一个数字,如果它后跟一个三个数字集(一个或多个)和一个点的序列".
测试:
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"
演示: http ://jsfiddle.net/hAfMM/9571/
您还可以扩展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"
演示/测试: http ://jsfiddle.net/hAfMM/435/
在此超级扩展版本中,您可以设置不同的分隔符类型:
/** * 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"
演示/测试: http ://jsfiddle.net/hAfMM/612/
Javascript有一个数字格式化程序(Internationalization API的一部分).
// Create our number formatter. var formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }); formatter.format(2500); /* $2,500.00 */
JS小提琴
用于undefined
代替第一个参数('en-US'
在示例中)以使用系统区域设置(如果代码在浏览器中运行,则为用户区域设置).
最后一点,将其与旧版本进行比较.toLocaleString
.它们都提供基本相同的功能.但是,toLocaleString在其旧版本(pre-Intl)中实际上不支持区域设置:它使用系统区域设置.因此,为了确保您使用的是正确的版本,MDN建议检查是否存在Intl
.所以,如果你还需要检查Intl,为什么不使用呢?但是,如果你选择使用垫片,那也是补丁Intl.NumberFormat
,所以在这种情况下你可以毫不费力地使用它:
(2500).toLocaleString('en-US', { style: 'currency', currency: 'USD', }); /* $2,500.00 */
如今,浏览器支持不再是一个问题,在美国/欧盟有97%的支持
对于世界其他地区(90%支持),支持方面最大的罪犯是UC Mobile(远离那个)和Opera Mini(设计瘫痪)
有一个垫片支持旧版浏览器
有关更多信息,请查看CanIUse
查看JavaScript Number对象,看看它是否对您有所帮助.
toLocaleString()
将使用特定于位置的千位分隔符格式化数字.
toFixed()
将数字四舍五入到特定的小数位数.
要同时使用这些值,必须将其类型更改回数字,因为它们都输出一个字符串.
例:
Number(someNumber.toFixed(1)).toLocaleString()
下面是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 [/sf/ask/17360801/] 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) : ''); }
这里有一些测试:
//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
不能再为空字符串(必须使用某种小数分隔符)
我们typeof thousands_sep === 'undefined'
按照如何最好地确定参数是否未发送到JavaScript函数的建议使用
(+n || 0)
因为this
是一个Number
对象所以不需要
JS小提琴
accounting.js是一个用于数字,货币和货币格式的小型JavaScript库.
如果金额是一个数字-123
,那么
amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
会产生字符串"-$123.00"
.
这是一个完整的工作示例.
这是我见过的最好的js money formatter:
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
你必须提供自己的货币代号(你使用上面的$).
像这样调用它(虽然注意args默认为2,逗号和句点,所以如果这是你的偏好,你不需要提供任何args):
var myMoney=3543.75873; var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
这里已经有了一些很棒的答案.这是另一种尝试,只是为了好玩:
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]; }
还有一些测试:
formatDollar(45664544.23423) // "$45,664,544.23" formatDollar(45) // "$45.00" formatDollar(123) // "$123.00" formatDollar(7824) // "$7,824.00" formatDollar(1) // "$1.00"
编辑:现在它也将处理负数
那么为什么没有人提出以下建议呢?
(2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2})
适用于大多数/某些浏览器:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Browser_Compatibility
我想你想要的是什么 f.nettotal.value = "$" + showValue.toFixed(2);
Numeral.js - 一个js库,可以通过@adamwdraper轻松编号
numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
好的,基于你所说的,我正在使用这个:
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;
我愿意改进建议(我不想仅仅为了这个而包括YUI :-))我已经知道我应该检测到"." 而不是仅仅使用它作为小数分隔符...
我使用的是Globalize库(来自Microsoft):
这是一个很好的项目来本地化数字,货币和日期,并根据用户区域设置自动格式化正确的方式!...尽管它应该是一个jQuery扩展,但它目前是一个100%独立的库.我建议大家试一试!:)
javascript-number-formatter(以前在Google Code上)
简短,快速,灵活但独立. 只有75行,包括麻省理工学院许可证信息,空白行和评论.
接受标准数字格式,如#,##0.00
或否定-000.####
.
接受任何国家像格式# ##0,00
,#,###.##
,#'###.##
或任何类型的非编号的象征.
接受任意数量的数字分组.#,##,#0.000
或者#,###0.##
都是有效的.
接受任何冗余/万无一失的格式.##,###,##.#
或者0#,#00#.###0#
一切都好.
自动编号舍入.
简单的界面,只需提供掩码和价值:format( "0.0000", 3.141592)
.
在掩码中包含前缀和后缀
(摘自其自述文件)
+1给Jonathan M提供原始方法.由于这显然是货币格式化程序,因此我继续将输出的货币符号(默认为'$')添加到输出中,并添加了一个默认逗号作为千位分隔符.如果您实际上不想要货币符号(或千位分隔符),只需使用""(空字符串)作为它的参数.
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) : ""); };
有一个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'
使用正则表达式的较短方法(用于插入空格,逗号或点)?
Number.prototype.toCurrencyString=function(){ return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 '); } n=12345678.9; alert(n.toCurrencyString());
Patrick Desjardins的回答看起来不错,但我更喜欢简单的javascript.这是我刚写的一个函数,用于输入数字并以货币格式返回(减去美元符号)
// 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]; }
有一个内置function
toFixed injavascript
var num = new Number(349); document.write("$" + num.toFixed(2));
还没见过这个.它非常简洁易懂.
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)
)
主要部分是插入千位分隔符,可以这样做:
我建议使用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.
这可能有点晚了,但这里有一个方法,我刚刚为同事准备了一个.toCurrencyString()
为所有数字添加语言环境感知功能的方法.内部化仅用于数字分组,而不是货币符号 - 如果您输出美元,则按"$"
提供使用,因为$123 4567
在日本或中国的美元数量$1,234,567
与美国相同.如果您输出欧元/等,则更改货币符号"$"
.
在HEAD或任何需要的任何地方声明这个,就在您需要使用它之前:
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; }
那你就完成了!使用(number).toCurrencyString()
您需要的任何地方输出数字作为货币.
var MyNumber = 123456789.125; alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13" MyNumber = -123.567; alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
通常,有多种方法可以做同样的事情,但我会避免使用,Number.prototype.toLocaleString
因为它可以根据用户设置返回不同的值.
我也不建议扩展Number.prototype
- 扩展本机对象原型是一种不好的做法,因为它可能导致与其他人代码(例如库/框架/插件)的冲突,并且可能与未来的JavaScript实现/版本不兼容.
我相信正则表达式是解决问题的最佳方法,这是我的实现:
/** * 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 (e.g. 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); } }
在2010/08/30编辑:添加了设置小数位数的选项. 在2011/08/23编辑:添加了将小数位数设置为零的选项.
以下是一些解决方案,全部通过测试套件,测试套件和基准测试,如果要复制和粘贴测试,请尝试使用此Gist.
方法0(RegExp)基于/sf/ask/17360801/,但如果没有小数点则修复.
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)); }分隔器
如果我们想要定制千位分隔符或小数分隔符,请使用replace()
:
123456.78.format(2).replace(',', ' ').replace('.', ' ');测试套件
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();
通过首先反转字符串和基本正则表达式来放置正确逗号的简单选项.
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(); };
我发现了这个:accounting.js.它非常容易,完全符合我的需要.
// 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€
Patrick Desjardins(前Daok)的例子对我很有用.如果有人有兴趣,我会移植到coffeescript.
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
YUI代码库使用以下formmating:
format: function(nData, oConfig) { oConfig = oConfig || {}; if(!YAHOO.lang.isNumber(nData)) { nData *= 1; } if(YAHOO.lang.isNumber(nData)) { var sOutput = nData + ""; var sDecimalSeparator = (oConfig.decimalSeparator) ? oConfig.decimalSeparator : "."; var nDotIndex; // Manage decimals if(YAHOO.lang.isNumber(oConfig.decimalPlaces)) { // Round to the correct decimal place var nDecimalPlaces = oConfig.decimalPlaces; var nDecimal = Math.pow(10, nDecimalPlaces); sOutput = Math.round(nData*nDecimal)/nDecimal + ""; nDotIndex = sOutput.lastIndexOf("."); if(nDecimalPlaces > 0) { // Add the decimal separator if(nDotIndex < 0) { sOutput += sDecimalSeparator; nDotIndex = sOutput.length-1; } // Replace the "." else if(sDecimalSeparator !== "."){ sOutput = sOutput.replace(".",sDecimalSeparator); } // Add missing zeros while((sOutput.length - 1 - nDotIndex) < nDecimalPlaces) { sOutput += "0"; } } } // Add the thousands separator if(oConfig.thousandsSeparator) { var sThousandsSeparator = oConfig.thousandsSeparator; nDotIndex = sOutput.lastIndexOf(sDecimalSeparator); nDotIndex = (nDotIndex > -1) ? nDotIndex : sOutput.length; var sNewOutput = sOutput.substring(nDotIndex); var nCount = -1; for (var i=nDotIndex; i>0; i--) { nCount++; if ((nCount%3 === 0) && (i !== nDotIndex)) { sNewOutput = sThousandsSeparator + sNewOutput; } sNewOutput = sOutput.charAt(i-1) + sNewOutput; } sOutput = sNewOutput; } // Prepend prefix sOutput = (oConfig.prefix) ? oConfig.prefix + sOutput : sOutput; // Append suffix sOutput = (oConfig.suffix) ? sOutput + oConfig.suffix : sOutput; return sOutput; } // Still not a Number, just return unaltered else { return nData; } }
它需要编辑,因为YUI库是可配置的,比如用"."替换oConfig.decimalSeparator.
Number(value)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
处理货币输出的功能,包括负数.
样本输出:
5.23
美元 - 5.23美元
function formatCurrency(total) { var neg = false; if(total < 0) { neg = true; total = Math.abs(total); } return (neg ? "-$" : '$') + parseFloat(total, 10).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").toString(); }
@tggagne是对的.由于浮动舍入,我的解决方案不好.并且toLocaleString函数缺少一些浏览器支持.我会留下以下评论,以便存档不做的事情.:)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString#Browser_Compatibility
(旧解决方案)使用Patrick Desjardins解决方案.
这是一个使用toLocaleString()的简洁解决方案,自Javascript 1.0版以来一直受支持.此示例将货币指定为美元,但可以使用"GBP"而非"USD"切换为磅.
var formatMoney = function (value) { // Convert the value to a floating point number in case it arrives as a string. var numeric = parseFloat(value); // Specify the local currency. return numeric.toLocaleString('USD', { style: 'currency', currency: "USD", minimumFractionDigits: 2, maximumFractionDigits: 2 }); }
有关其他详细信息,请参阅https://marcoscaceres.github.io/jsi18n/#localize_currency.
55个答案明显要求另一个答案
function centsToDollaString(x){ var cents = x + "" while(cents.length < 4){ cents = "0" + cents; } var dollars = cents.substr(0,cents.length - 2) var decimal = cents.substr(cents.length - 2, 2) while(dollars.length % 3 != 0){ dollars = "0" + dollars; } str = dollars.replace(/(\d{3})(?=\d)/g, "$1" + ",").replace(/^0*(?=.)/,""); return "$" + str + "." + decimal; }
http://code.google.com/p/javascript-number-formatter/:
简短,快速,灵活但独立.只有75行,包括麻省理工学院许可证信息,空白行和评论.
接受标准数字格式,如#,## 0.00或否定-000.####.
接受任何国家/地区格式,如### 0,00,#,###.##,#'###.##或任何类型的非编号符号.
接受任意数量的数字分组.#,##,#0.000或#,### 0.##都有效.
接受任何冗余/万无一失的格式.##,###,##.#或0#,#00#.### 0#都没关系.
自动编号舍入.
简单的界面,只提供这样的掩码和值:格式("0.0000",3.141592)
更新这是我pp
用于大多数常见任务的本地实用程序:
var NumUtil = {}; /** Petty print 'num' wth exactly 'signif' digits. pp(123.45, 2) == "120" pp(0.012343, 3) == "0.0123" pp(1.2, 3) == "1.20" */ NumUtil.pp = function(num, signif) { if (typeof(num) !== "number") throw 'NumUtil.pp: num is not a number!'; if (isNaN(num)) throw 'NumUtil.pp: num is NaN!'; if (num < 1e-15 || num > 1e15) return num; var r = Math.log(num)/Math.LN10; var dot = Math.floor(r) - (signif-1); r = r - Math.floor(r) + (signif-1); r = Math.round(Math.exp(r * Math.LN10)).toString(); if (dot >= 0) { for (; dot > 0; dot -= 1) r += "0"; return r; } else if (-dot >= r.length) { var p = "0."; for (; -dot > r.length; dot += 1) { p += "0"; } return p+r; } else { return r.substring(0, r.length + dot) + "." + r.substring(r.length + dot); } } /** Append leading zeros up to 2 digits. */ NumUtil.align2 = function(v) { if (v < 10) return "0"+v; return ""+v; } /** Append leading zeros up to 3 digits. */ NumUtil.align3 = function(v) { if (v < 10) return "00"+v; else if (v < 100) return "0"+v; return ""+v; } NumUtil.integer = {}; /** Round to integer and group by 3 digits. */ NumUtil.integer.pp = function(num) { if (typeof(num) !== "number") { console.log("%s", new Error().stack); throw 'NumUtil.integer.pp: num is not a number!'; } if (isNaN(num)) throw 'NumUtil.integer.pp: num is NaN!'; if (num > 1e15) return num; if (num < 0) throw 'Negative num!'; num = Math.round(num); var group = num % 1000; var integ = Math.floor(num / 1000); if (integ === 0) { return group; } num = NumUtil.align3(group); while (true) { group = integ % 1000; integ = Math.floor(integ / 1000); if (integ === 0) return group + " " + num; num = NumUtil.align3(group) + " " + num; } return num; } NumUtil.currency = {}; /** Round to coins and group by 3 digits. */ NumUtil.currency.pp = function(amount) { if (typeof(amount) !== "number") throw 'NumUtil.currency.pp: amount is not a number!'; if (isNaN(amount)) throw 'NumUtil.currency.pp: amount is NaN!'; if (amount > 1e15) return amount; if (amount < 0) throw 'Negative amount!'; if (amount < 1e-2) return 0; var v = Math.round(amount*100); var integ = Math.floor(v / 100); var frac = NumUtil.align2(v % 100); var group = integ % 1000; integ = Math.floor(integ / 1000); if (integ === 0) { return group + "." + frac; } amount = NumUtil.align3(group); while (true) { group = integ % 1000; integ = Math.floor(integ / 1000); if (integ === 0) return group + " " + amount + "." + frac; amount = NumUtil.align3(group) + " " + amount; } return amount; }
国际编号格式
var number = 3500; alert(new Intl.NumberFormat().format(number)); // ? "3,500" if in US English locale
或phpjs.com/functions/number_format