Gostaria de formatar um preço em JavaScript. Eu gostaria de uma função que leva a float
como argumento e retorna um string
formatado como este:
"$ 2,500.00"
Qual é a melhor forma de fazer isso?
Gostaria de formatar um preço em JavaScript. Eu gostaria de uma função que leva a float
como argumento e retorna um string
formatado como este:
"$ 2,500.00"
Qual é a melhor forma de fazer isso?
Respostas:
Esta solução é compatível com todos os principais navegadores principais:
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)
Tudo que você precisa é adicionar o símbolo da moeda (por exemplo "$" + profits.toFixed(2)
) e você terá seu valor em dólares.
Se você precisar usar ,
entre cada dígito, poderá usar esta função:
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>
Use-o assim:
(123456789.12345).formatMoney(2, ".", ",");
Se você sempre usará '.' e ',', você pode excluí-los da chamada de método, e o método os padronizará para você.
(123456789.12345).formatMoney(2);
Se sua cultura possui os dois símbolos invertidos (europeus) e você deseja usar os padrões, cole as duas linhas a seguir no formatMoney
método:
d = d == undefined ? "," : d,
t = t == undefined ? "." : t,
Se você pode usar a sintaxe moderna do ECMAScript (por exemplo, através do Babel), pode usar esta função mais simples:
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>
d
e t
para .
e e, ,
respectivamente, para não precisar especificá-los sempre. Além disso, eu recomendo modificar o início da return
declaração para ler return s + '$' + [rest]
:, caso contrário você não receberá um cifrão.
Javascript tem um formatador de números (parte da API de internacionalização).
// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
});
formatter.format(2500); /* $2,500.00 */
Use undefined
no lugar do primeiro argumento ( 'en-US'
no exemplo) para usar a localidade do sistema (a localidade do usuário, caso o código esteja sendo executado em um navegador). Mais explicações sobre o código de localidade .
Aqui está uma lista dos códigos de moeda .
Uma nota final comparando isso com o anterior. toLocaleString
. Ambos oferecem essencialmente a mesma funcionalidade. No entanto, toLocaleString em suas encarnações mais antigas (pré-Intl) na verdade não suporta localidades : ele usa a localidade do sistema. Portanto, verifique se você está usando a versão correta (o MDN sugere verificar a existência deIntl
). Além disso, o desempenho de ambos é o mesmo para um único item, mas se você tiver muitos números para formatar, o uso Intl.NumberFormat
será aproximadamente 70 vezes mais rápido. Aqui está como usar toLocaleString
:
(2500).toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
}); /* $2,500.00 */
(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); // 12,345.67
A idéia por trás dessa solução é substituir as seções correspondentes pela primeira correspondência e vírgula, ou seja '$&,'
. A correspondência é feita usando a abordagem lookahead . Você pode ler a expressão como "corresponder a um número se for seguida por uma sequência de três conjuntos de números (um ou mais) e um ponto" .
ENSAIOS:
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/9571/
Você também pode estender o protótipo de Number
objeto para adicionar suporte adicional a qualquer número de casas decimais [0 .. n]
e ao tamanho dos grupos de números [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"
DEMO / TESTES: http://jsfiddle.net/hAfMM/435/
Nesta versão super estendida, você pode definir diferentes tipos de delimitadores:
/**
* 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"
DEMO / TESTES: http://jsfiddle.net/hAfMM/612/
.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")
.
Number.prototype.toMoney = (decimal=2) -> @toFixed(decimal).replace /(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,"
\.
por $
(fim de linha), ie this.toFixed(0).replace(/(\d)(?=(\d{3})+$)/g, "$1,")
.
$1,
. A correspondência é feita usando a abordagem lookahead . Você pode ler a expressão como "corresponder a um número se for seguida por uma sequência de três conjuntos de números (um ou mais) e um ponto" .
Dê uma olhada no objeto JavaScript Number e veja se ele pode ajudá-lo.
toLocaleString()
formatará um número usando o separador de milhares específico do local. toFixed()
arredondará o número para um número específico de casas decimais.Para usá-los ao mesmo tempo, o valor deve ter seu tipo alterado de volta para um número, porque ambos produzem uma sequência.
Exemplo:
Number((someNumber).toFixed(1)).toLocaleString()
toLocaleString
que use o código do idioma do sistema e uma nova (incompatível) proveniente da API ECMAScript Intl. Explicado aqui . Esta resposta parece ser destinada à versão antiga.
Abaixo está o código de Patrick Desjardins (também conhecido como Daok) com alguns comentários adicionados e algumas pequenas alterações:
/*
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 [/programming/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) : '');
}
e aqui alguns testes:
//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));
As pequenas alterações são:
mudou um pouco a Math.abs(decimals)
ser feito apenas quando não é NaN
.
decimal_sep
não pode mais ser uma string vazia (um tipo de separador decimal é obrigatório)
usamos typeof thousands_sep === 'undefined'
como sugerido em Qual a melhor forma de determinar se um argumento não é enviado para a função JavaScript
(+n || 0)
não é necessário porque this
é um Number
objeto
parseInt
chama-se sobre o valor absoluto da parte inteira do número. A parte INTEGER não pode começar com ZERO, a menos que seja apenas um ZERO! E parseInt(0) === 0
octal ou decimal.
0
é considerado octal por parseInt
. Mas neste código é IMPOSSÍVEL parseInt
receber 016
como entrada (ou qualquer outro valor formatado octal), porque o argumento passado parseInt
é o primeiro processado pela Math.abs
função. Portanto, não há como parseInt
receber um número que começa com zero, a menos que seja apenas zero ou 0.nn
(onde nn
são decimais). Mas ambos 0
e 0.nn
strings seriam convertidos parseInt
em um ZERO simples, como deveria ser.
accounting.js é uma pequena biblioteca JavaScript para formatação de números, dinheiro e moeda.
Se quantidade é um número, digamos -123
, então
amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
irá produzir a string "-$123.00"
.
Aqui está um exemplo completo de trabalho .
minimumFractionDigits: 0
Aqui está o melhor formatador js money que eu já vi:
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) : "");
};
Foi reformatado e emprestado a partir daqui: https://stackoverflow.com/a/149099/751484
Você precisará fornecer seu próprio designador de moeda (você usou $ acima).
Chame assim (embora observe que os argumentos padrão são 2, vírgula e ponto; portanto, você não precisa fornecer argumentos, se essa for a sua preferência):
var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
var
declaração.
Já existem ótimas respostas aqui. Aqui está outra tentativa, apenas por diversão:
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];
}
E alguns testes:
formatDollar(45664544.23423) // "$45,664,544.23"
formatDollar(45) // "$45.00"
formatDollar(123) // "$123.00"
formatDollar(7824) // "$7,824.00"
formatDollar(1) // "$1.00"
Editado: agora ele também manipula números negativos
i = orig.length - i - 1
no retorno de chamada. Ainda assim, menos uma travessia da matriz.
reduce
método foi introduzido no Ecmascript 1.8 e não é suportado no Internet Explorer 8 e abaixo.
Funciona para todos os navegadores atuais
Use toLocaleString
para formatar uma moeda em sua representação sensível ao idioma (usando códigos de moeda ISO 4217 ).
(2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2})
Exemplo de trechos de código Rand sul-africano para @avenmore
console.log((2500).toLocaleString("en-ZA", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> R 2 500,00
console.log((2500).toLocaleString("en-GB", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> ZAR 2,500.00
Eu acho que o que você quer é f.nettotal.value = "$" + showValue.toFixed(2);
Numeral.js - uma biblioteca js para facilitar a formatação de números por @adamwdraper
numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
Ok, com base no que você disse, eu estou usando isso:
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;
Estou aberto a sugestões de melhorias (eu preferiria não incluir a YUI apenas para fazer isso :-)) Eu já sei que deveria estar detectando o "." em vez de apenas usá-lo como separador decimal ...
Eu uso a biblioteca Globalize (da Microsoft):
É um ótimo projeto localizar números, moedas e datas e formatá-los automaticamente da maneira certa, de acordo com a localidade do usuário! ... e, apesar de ser uma extensão do jQuery, atualmente é uma biblioteca 100% independente. Eu sugiro a todos que experimentem! :)
formatador de número javascript (anteriormente no Google Code )
#,##0.00
ou com negação -000.####
.# ##0,00
, #,###.##
,#'###.##
ou qualquer tipo de símbolo não-numeração.#,##,#0.000
ou #,###0.##
são todos válidos.##,###,##.#
ou 0#,#00#.###0#
estão todos bem.format( "0.0000", 3.141592)
.(trecho do seu README)
+1 a Jonathan M por fornecer o método original. Como este é explicitamente um formatador de moeda, fui adiante e adicionei o símbolo da moeda (o padrão é '$') à saída e adicionei uma vírgula padrão como separador de milhares. Se você realmente não deseja um símbolo de moeda (ou separador de milhares), basta usar "" (sequência vazia) como argumento para isso.
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) : "");
};
+n || 0
é a única coisa que parece um pouco estranha (para mim de qualquer maneira).
this
é um nome de variável perfeitamente útil. Convertê-lo para n
salvar três caracteres no momento da definição pode ter sido necessário em uma época em que a RAM e a largura de banda eram contadas em KB, mas é simplesmente ofuscante em uma época em que o minifier cuidará de tudo isso antes de atingir a produção. As outras micro otimizações inteligentes são pelo menos discutíveis.
Existe uma porta javascript da função PHP "number_format".
Acho muito útil, pois é fácil de usar e reconhecível pelos desenvolvedores de 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;
}
(Bloco de comentários do original , incluído abaixo para exemplos e crédito, quando devido)
// 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'
Um método mais curto (para inserir espaço, vírgula ou ponto) com expressão regular?
Number.prototype.toCurrencyString=function(){
return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 ');
}
n=12345678.9;
alert(n.toCurrencyString());
Não vi nada assim. É bem conciso e fácil de entender.
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)
)
Aqui está uma versão com mais opções na saída final para permitir a formatação de diferentes moedas em diferentes formatos de localidade.
// 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)
)
A resposta de Patrick Desjardins parece boa, mas eu prefiro meu javascript simples. Aqui está uma função que acabei de escrever para pegar um número e devolvê-lo no formato de moeda (menos o cifrão)
// 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];
}
A parte principal é inserir os mil separadores, que poderiam ser feitos assim:
<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)));">
Há um built-in function
toFixed emjavascript
var num = new Number(349);
document.write("$" + num.toFixed(2));
toFixed()
toFixed()
é uma função do Number
objeto e não funcionará var num
se for um String
, portanto o contexto adicional me ajudou.
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;
}
De WillMaster .
Sugiro a classe NumberFormat da API de visualização do Google .
Você pode fazer algo assim:
var formatter = new google.visualization.NumberFormat({
prefix: '$',
pattern: '#,###,###.##'
});
formatter.formatValue(1000000); // $ 1,000,000
Espero que ajude.
Pode ser um pouco tarde, mas aqui está um método que acabei de criar para um colega de trabalho para adicionar uma .toCurrencyString()
função com reconhecimento de localidade a todos os números. A internalização é apenas para agrupamento de números, NÃO para o sinal de moeda - se você estiver produzindo dólares, use "$"
como fornecido, porque $123 4567
no Japão ou na China é o mesmo número de dólares que $1,234,567
aqui nos EUA. Se você estiver produzindo euro / etc., Altere o sinal de moeda de"$"
.
Declare isso em qualquer lugar do seu HEAD ou sempre que necessário, antes de precisar usá-lo:
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;
}
Então você está pronto! Use em (number).toCurrencyString()
qualquer lugar que você precise exibir o número como moeda.
var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
Como geralmente, existem várias maneiras de fazer a mesma coisa, mas eu evitaria usá- Number.prototype.toLocaleString
lo, pois ele pode retornar valores diferentes com base nas configurações do usuário.
Também não recomendo estender o Number.prototype
protótipo de objetos nativos é uma prática ruim, pois pode causar conflitos com o código de outras pessoas (por exemplo, bibliotecas / estruturas / plugins) e pode não ser compatível com futuras implementações / versões de JavaScript.
Acredito que expressões regulares são a melhor abordagem para o problema, aqui está a minha implementação:
/**
* 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);
}
}
editado em 30/08/2010: opção adicionada para definir o número de dígitos decimais. editado em 23/08/2011: opção adicionada para definir o número de dígitos decimais como zero.
Aqui estão algumas soluções: todas passam no conjunto de testes, no conjunto de testes e no benchmark incluídos. Se você deseja copiar e colar para testar, tente This Gist .
Baseie-se em https://stackoverflow.com/a/14428340/1877620 , mas corrija se não houver ponto decimal.
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('.');
}
}
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('.');
};
}
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('.');
};
}
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));
}
Se quisermos separador de milhares personalizado ou separador decimal, use 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();
Number(value)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
Uma opção simples para o posicionamento correto da vírgula, revertendo a cadeia de caracteres primeiro e a regexp básica.
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();
};
Encontrei isso em: accounting.js . É muito fácil e se encaixa perfeitamente na minha necessidade.
// 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€
formatNumber
no javascript