如何在JavaScript中将数字格式化为货币字符串? Intl.numberformat

问题描述 投票:1561回答:62

我想用JavaScript格式化价格。 我想要一个以float为参数的函数,并返回一个格式如下的string

"$ 2,500.00"

最好的方法是什么?

javascript formatting currency
62个回答
1674
投票

Number.prototype.toFixed

此解决方案与每个主要浏览器兼容:

  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);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

像这样使用它:

(123456789.12345).formatMoney(2, ".", ",");

如果你总是要使用'。'和',',你可以让他们离开你的方法调用,该方法将默认为你。

(123456789.12345).formatMoney(2);

如果您的文化中有两个符号翻转(即欧洲人)并且您想使用默认值,只需在formatMoney方法中粘贴以下两行:

    d = d == undefined ? "," : d, 
    t = t == undefined ? "." : t, 

自定义功能(ES6)

如果您可以使用现代ECMAScript语法(即通过Babel),您可以使用这个更简单的函数:

function formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") {
  try {
    decimalCount = Math.abs(decimalCount);
    decimalCount = isNaN(decimalCount) ? 2 : decimalCount;

    const negativeSign = amount < 0 ? "-" : "";

    let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
    let j = (i.length > 3) ? i.length % 3 : 0;

    return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "");
  } catch (e) {
    console.log(e)
  }
};
document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

69
投票

我想你想要的是formatDollar(45664544.23423) // "$45,664,544.23" formatDollar(45) // "$45.00" formatDollar(123) // "$123.00" formatDollar(7824) // "$7,824.00" formatDollar(1) // "$1.00"


64
投票

那么为什么没有人提出以下建议呢?

f.nettotal.value = "$" + showValue.toFixed(2);

适用于大多数/某些浏览器:

(2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2})


26
投票

好的,根据你所说的,我正在使用这个:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Browser_Compatibility

我愿意改进建议(我不想仅仅为了这个而包括YUI :-))我已经知道我应该检测到“。”而不是仅仅使用它作为小数分隔符...


26
投票

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; - 一个js库,可以通过@adamwdraper轻松编号

Numeral.js

25
投票

我使用库numeral(23456.789).format('$0,0.00'); // = "$23,456.79" (来自Microsoft):

这是一个很好的项目来本地化数字,货币和日期,并根据用户区域设置自动格式化正确的方式! ...尽管它应该是一个jQuery扩展,但它目前是一个100%独立的库。我建议大家试一试! :)


24
投票

Globalize(以前在javascript-number-formatter

  • 简短,快速,灵活但独立。 只有75行,包括麻省理工学院许可证信息,空白行和评论。
  • 接受标准数字格式,如Google Code或否定#,##0.00
  • 接受任何国家/地区格式,如-000.##### ##0,00#,###.##或任何类型的非编号符号。
  • 接受任意数量的数字分组。 #'###.###,##,#0.000都是有效的。
  • 接受任何冗余/万无一失的格式。 #,###0.####,###,##.#都行。
  • 自动编号舍入。
  • 简单的界面,只需提供这样的掩码和价值:0#,#00#.###0#
  • 在掩码中包含前缀和后缀

(摘自其自述文件)


21
投票

有一个PHP函数“number_format”的javascript端口。

我发现它非常有用,因为它易于使用并且可以被PHP开发人员识别。

format( "0.0000", 3.141592)

(来自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; } 的评论栏,下面包含示例和信用到期)

the original

21
投票

+1给Jonathan M提供原始方法。由于这显然是货币格式化程序,因此我继续将输出的货币符号(默认为'$')添加到输出中,并添加了一个默认逗号作为千位分隔符。如果您实际上不想要货币符号(或千位分隔符),只需使用“”(空字符串)作为它的参数。

// 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'

20
投票

使用正则表达式的较短方法(用于插入空格,逗号或点)?

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) : "");
};

16
投票

Number.prototype.toCurrencyString=function(){ return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 '); } n=12345678.9; alert(n.toCurrencyString()); 的答案看起来不错,但我更喜欢简单的javascript。这是我刚写的一个函数,用于输入数字并以货币格式返回(减去美元符号)

Patrick Desjardins

1206
投票

简短快速的解决方案(无处不在!)

(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');  // 12,345.67

这个解决方案背后的想法是用第一个匹配和逗号替换匹配的部分,即'$&,'。匹配是使用lookahead approach完成的。您可以将表达式读作“匹配一个数字,如果它后跟一个三个数字集(一个或多个)和一个点的序列”。

测试:

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"

但是:ぁzxswい


扩展的短解决方案

您还可以扩展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/中,您可以设置不同的分隔符类型:

super extended version

演示/测试:/** * 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"


16
投票

// 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

javascript

15
投票

主要部分是插入千位分隔符,可以这样做:

var num = new Number(349);
document.write("$" + num.toFixed(2));

15
投票

我建议来自<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)));"> 的NumberFormat类。

你可以这样做:

Google Visualization API

我希望它有所帮助。


15
投票

还没见过这个。它非常简洁易懂。

var formatter = new google.visualization.NumberFormat({
    prefix: '$',
    pattern: '#,###,###.##'
});

formatter.formatValue(1000000); // $ 1,000,000

这是在最终输出中具有更多选项的版本,以允许以不同的地点格式格式化不同的货币。

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)
)

14
投票
// higher order function that takes options then a price and will return the formatted price
const makeMoneyFormatter = ({
  sign = '$',
  delimiter = ',',
  decimal = '.',
  append = false,
  precision = 2,
  round = true,
  custom
} = {}) => value => {
  
  const e = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]
  
  value = round
    ? (Math.round(value * e[precision]) / e[precision])
    : parseFloat(value)
  
  const pieces = value
    .toFixed(precision)
    .replace('.', decimal)
    .split('')
  
  let ii = pieces.length - (precision ? precision + 1 : 0)
  
  while ((ii-=3) > 0) {
    pieces.splice(ii, 0, delimiter)
  }
  
  if (typeof custom === 'function') {
    return custom({
      sign,
      float: value, 
      value: pieces.join('') 
    })
  }
  
  return append
    ? pieces.join('') + sign
    : sign + pieces.join('')
}

// create currency converters with the correct formatting options
const formatDollar = makeMoneyFormatter()
const formatPound = makeMoneyFormatter({ 
  sign: '£',
  precision: 0
})
const formatEuro = makeMoneyFormatter({
  sign: '€',
  delimiter: '.',
  decimal: ',',
  append: true
})

const customFormat = makeMoneyFormatter({
  round: false,
  custom: ({ value, float, sign }) => `SALE:$${value}USD`
})

console.log(
  formatPound(1000),
  formatDollar(10000.0066),
  formatEuro(100000.001),
  customFormat(999999.555)
)

来自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; }


14
投票

这可能有点晚了,但这是我为同事准备的方法,为所有数字添加一个区域设置感知的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()

12
投票

通常,有多种方法可以做同样的事情,但我会避免使用var MyNumber = 123456789.125; alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13" MyNumber = -123.567; alert(MyNumber.toCurrencyString()); // alerts "$-123.57" ,因为它可以根据用户设置返回不同的值。

我也不建议扩展Number.prototype.toLocaleString - 扩展本机对象原型是一种不好的做法,因为它可能导致与其他人代码(例如库/框架/插件)的冲突,并且可能与未来的JavaScript实现/版本不兼容。

我相信正则表达式是解决问题的最佳方法,这是我的实现:

Number.prototype

在2010/08/30编辑:添加了设置小数位数的选项。在2011/08/23编辑:添加了将小数位数设置为零的选项。


11
投票

我发现了这个:/** * 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); } } 。它非常容易,完全符合我的需要。


10
投票

通过首先反转字符串和基本正则表达式来放置正确逗号的简单选项。

// 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€ 

10
投票

以下是一些解决方案,全部通过测试套件,测试套件和基准测试,如果要复制和粘贴测试,请尝试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(); };

Method 0 (RegExp)

基于This Gist,但如果没有小数点则修复。

https://stackoverflow.com/a/14428340/1877620

Method 1

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('.');
    }
}

Method 2 (Split to Array)

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('.');
    };
}

Method 3 (Loop)

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('.');
    };
}

Usage Example

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('');
    };
}

Separator

如果我们想要自定义千位分隔符或小数分隔符,请使用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()

Test suite

123456.78.format(2).replace(',', ' ').replace('.', ' ');

Benchmark

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);

1088
投票

http://jsfiddle.net/hAfMM/612/

Javascript有一个数字格式化程序(Internationalization API的一部分)。

Intl.numberformat

// Create our number formatter. var formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }); formatter.format(2500); /* $2,500.00 */

使用JS fiddle代替第一个参数(示例中为undefined)以使用系统区域设置(如果代码在浏览器中运行,则为用户区域设置)。

Intl.NumberFormat与Number.prototype.toLocaleString

最后一点,将其与较旧的.'en-US'进行比较。它们都提供基本相同的功能。但是,toLocaleString在它的旧版本(pre-Intl)toLocaleString中:它使用系统区域设置。因此,请确保您使用的是正确的版本(does not actually support locales)。此外,对于单个项目,两者的性能相同,但如果要格式化大量数字,使用MDN suggests to check for the existence of Intl的速度要快70倍。以下是如何使用Intl.NumberFormat

toLocaleString

Some notes on browser support

  • 如今,浏览器支持不再是一个问题,在美国/欧盟有97%的支持
  • 对于世界其他地区(92%支持),支持方面最大的罪犯是UC Mobile((2500).toLocaleString('en-US', { style: 'currency', currency: 'USD', }); /* $2,500.00 */ )和Opera Mini(设计瘫痪)
  • 在旧版浏览器上有一个stay away from that支持它
  • 有关更多信息,请查看shim

9
投票

Patrick Desjardins(前Daok)的例子对我很有用。如果有人有兴趣,我会移植到coffeescript。

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();

201
投票

看看JavaScript CanIUse对象,看它是否可以帮助你。

  • Number将使用特定于位置的千位分隔符格式化数字。
  • toLocaleString()会将数字四舍五入到特定的小数位数。

要同时使用这些值,必须将其类型更改回数字,因为它们都输出一个字符串。

例:

toFixed()

160
投票

下面是Number(someNumber.toFixed(1)).toLocaleString() 代码,添加了一些注释和一些小的更改:

Patrick Desjardins (alias 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) : ''); 
}

微小的变化是:

  1. 移动了一点//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)时才能完成。
  2. NaN不能再为空字符串(必须使用某种小数分隔符)
  3. 我们在decimal_sep中建议使用typeof thousands_sep === 'undefined'
  4. 因为How best to determine if an argument is not sent to the JavaScript function是一个(+n || 0)对象,所以不需要this

Number


122
投票

JS Fiddle是一个用于数字,金钱和货币格式的小型JavaScript库。


114
投票

如果金额是一个数字,比如accounting.js,那么

-123

将产生字符串amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });

这是一个完整的"-$123.00"工作。


98
投票

这是我见过的最好的js money格式化程序:

example

它被重新格式化并从这里借来: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) : ""); };

你必须提供自己的货币代号(你使用上面的$)。

像这样调用它(虽然注意args默认为2,逗号和句点,所以如果这是你的偏好,你不需要提供任何args):

https://stackoverflow.com/a/149099/751484

72
投票

这里已经有了一些很棒的答案。这是另一种尝试,只是为了好玩:

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];
}

编辑:现在它也将处理负数

© www.soinside.com 2019 - 2024. All rights reserved.