numero - ¿Cómo puedo dar formato a los números en dólares como cadena de moneda en JavaScript?
numberformat javascript (30)
Intl.numberformat
Javascript tiene un formateador de números (parte de la API de internacionalización).
// 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 */
Use undefined
en lugar del primer argumento ( ''en-US''
en el ejemplo) para usar la configuración regional del sistema (la configuración regional del usuario en caso de que el código se ejecute en un navegador).
Intl.NumberFormat vs Number.prototype.toLocaleString
Una nota final comparando esto con la anterior. toLocaleString
. Ambos ofrecen esencialmente la misma funcionalidad. Sin embargo, toLocaleString en sus encarnaciones anteriores (pre-Intl) no es compatible con las configuraciones regionales : utiliza la configuración regional del sistema. Por lo tanto, para asegurarse de que está utilizando la versión correcta, MDN sugiere verificar la existencia de Intl
. Entonces, si necesitas buscar Intl de todos modos, ¿por qué no usarlo? Sin embargo, si eliges usar el shim, eso también parchea toLocaleString
, así que en ese caso puedes usarlo sin ningún problema:
(2500).toLocaleString(''en-US'', {
style: ''currency'',
currency: ''USD'',
}); /* $2,500.00 */
Algunas notas sobre el soporte del navegador.
- El soporte del navegador ya no es un problema hoy en día con un 97% de soporte en los EE. UU. / UE
- Para otras partes del mundo (90% compatible), los mayores infractores en términos de asistencia son UC Mobile ( aléjate de eso ) y Opera Mini (paralizado por el diseño)
- Hay un shim para soportarlo en navegadores antiguos
- Echa un vistazo a CanIUse para más información.
Me gustaría formatear un precio en JavaScript.
Me gustaría una función que tome un float
como argumento y devuelva una string
formato:
"$ 2,500.00"
¿Cuál es la mejor manera de hacer esto?
Solución corta y rápida (funciona en todas partes!)
(12345.67).toFixed(2).replace(//d(?=(/d{3})+/.)/g, ''$&,''); // 12,345.67
La idea detrás de esta solución es reemplazar las secciones combinadas con la primera coincidencia y la coma, es decir, ''$&,''
. El emparejamiento se realiza mediante el enfoque de búsqueda anticipada Puede leer la expresión como "coincide con un número si va seguida de una secuencia de tres conjuntos de números (uno o más) y un punto" .
Pruebas:
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/
Solución corta extendida
También puede extender el prototipo del objeto Number
para agregar soporte adicional de cualquier número de decimales [0 .. n]
y el tamaño de los 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 / PRUEBAS: http://jsfiddle.net/hAfMM/435/
Solución corta súper extendida
En esta versión súper extendida puedes configurar 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 / PRUEBAS: http://jsfiddle.net/hAfMM/612/
Number.prototype.toFixed
Esta solución es compatible con todos los principales navegadores:
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)
Todo lo que necesita es agregar el símbolo de moneda (por ejemplo, "$" + profits.toFixed(2)
) y tendrá su monto en dólares.
Función personalizada
Si requiere el uso de ,
entre cada dígito, puede usar esta función:
function formatMoney(n, c, d, t) {
var 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) : "");
};
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>
Úsalo así:
(123456789.12345).formatMoney(2, ".", ",");
Si siempre vas a usar ''.'' y '','', puede dejarlos fuera de su llamada de método, y el método los predeterminará por usted.
(123456789.12345).formatMoney(2);
Si su cultura tiene los dos símbolos invertidos (es decir, europeos) y le gustaría usar los valores predeterminados, simplemente pegue las siguientes dos líneas en el método formatMoney
:
d = d == undefined ? "," : d,
t = t == undefined ? "." : t,
Función personalizada (ES6)
Si puede usar la sintaxis ECMAScript moderna (es decir, a través de Babel), puede usar esta función más simple en su lugar:
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>
+1 a Jonathan M por proporcionar el método original. Como esto es explícitamente un formateador de moneda, seguí adelante y agregué el símbolo de moneda (por defecto a ''$'') a la salida, y agregué una coma predeterminada como el separador de miles. Si en realidad no desea un símbolo de moneda (o un separador de miles), simplemente use "" (cadena vacía) como su argumento para ello.
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) : "");
};
A continuación se muestra el código de Patrick Desjardins (alias Daok) con algunos comentarios agregados y algunos cambios menores:
/*
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://.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) : '''');
}
Y aquí algunas pruebas:
//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));
Los cambios menores son:
movió un poco los
Math.abs(decimals)
para hacer solo cuando no esNaN
.decimal_sep
ya no puede ser una cadena vacía (esdecimal_sep
algún tipo de separador decimal)usamos
typeof thousands_sep === ''undefined''
como se sugiere en Cómo determinar mejor si un argumento no se envía a la función de JavaScript(+n || 0)
no es necesario porque se trata de un objetoNumber
Aquí está el mejor formateador de js money que he visto:
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) : "");
};
Se volvió a formatear y se tomó prestado desde aquí: https://.com/a/149099/751484
Tendrá que proporcionar su propio designador de moneda (usó $ arriba).
Llámelo de esta manera (aunque tenga en cuenta que los argumentos por defecto son 2, coma y punto, por lo que no es necesario que proporcione ningún argumento si así lo prefiere):
var myMoney=3543.75873;
var formattedMoney = ''$'' + myMoney.formatMoney(2,'','',''.''); // "$3,543.76"
Creo que lo que quieres es f.nettotal.value = "$" + showValue.toFixed(2);
Eche un vistazo al objeto Number JavaScript y vea si le puede ayudar.
-
toLocaleString()
formateará un número usando el separador de miles de ubicaciones específicas. -
toFixed()
redondeará el número a un número específico de lugares decimales.
Para usarlos al mismo tiempo, el valor debe cambiar su tipo a un número porque ambos generan una cadena.
Ejemplo:
Number(someNumber.toFixed(1)).toLocaleString()
Entonces, ¿por qué nadie ha sugerido lo siguiente?
(2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2})
Funciona para la mayoría / algunos navegadores:
Hay un puerto javascript de la función PHP "number_format".
Me parece muy útil ya que es fácil de usar y reconocible para los desarrolladores 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;
}
(Bloque de comentarios del original , incluido a continuación para ejemplos y crédito cuando corresponda)
// 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''
Ok, basado en lo que dijiste, estoy usando esto:
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;
Estoy abierto a sugerencias de mejora (preferiría no incluir YUI solo para hacer esto :-)) Ya sé que debería estar detectando el "." En lugar de utilizarlo como separador decimal ...
Si la cantidad es un número, digamos -123
, entonces
amount.toLocaleString(''en-US'', { style: ''currency'', currency: ''USD'' });
producirá la cadena "-$123.00"
.
Aquí hay un example completo de trabajo.
Utilizo la biblioteca Globalize (de Microsoft):
¡Es un gran proyecto para localizar números, monedas y fechas y tenerlos automáticamente formateados de la manera correcta de acuerdo con la configuración regional del usuario! ... ya pesar de que debería ser una extensión de jQuery, actualmente es una biblioteca 100% independiente. Les sugiero a todos que lo prueben! :)
Ya hay algunas grandes respuestas aquí. Aquí hay otro intento, sólo por diversión:
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];
}
Y algunas pruebas:
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: ahora manejará números negativos también
¿Un método más corto (para insertar espacio, coma o punto) con expresión regular?
Number.prototype.toCurrencyString=function(){
return this.toFixed(2).replace(/(/d)(?=(/d{3})+/b)/g,''$1 '');
}
n=12345678.9;
alert(n.toCurrencyString());
Numeral.js : una biblioteca js para un fácil formateo de números por @adamwdraper
numeral(23456.789).format(''$0,0.00''); // = "$23,456.79"
accounting.js es una pequeña biblioteca de JavaScript para el formato de números, dinero y moneda.
javascript-number-formatter (anteriormente en Google Code )
- Corto, rápido, flexible y autónomo.
Solo 75 líneas, incluida la información de la licencia MIT, líneas en blanco y comentarios. - Acepte el formato de número estándar como
#,##0.00
o con la negación-000.####
. - Acepte cualquier formato de país como
# ##0,00
,#,###.##
,#''###.##
o cualquier tipo de símbolo de no numeración. - Acepta cualquier número de agrupación de dígitos.
#,##,#0.000
o#,###0.##
son todos válidos. - Acepte cualquier formato redundante / a prueba de tontos.
##,###,##.#
o0#,#00#.###0#
están todos bien. - Redondeo automático de números.
- Interfaz simple, solo suministre máscara y valor como este:
format( "0.0000", 3.141592)
. - Incluir un prefijo y sufijo con la máscara
(extracto de su README)
La parte principal es insertar los mil separadores, que se podrían hacer así:
<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)));">
La respuesta de Patrick Desjardins se ve bien, pero prefiero mi javascript simple. Aquí hay una función que acabo de escribir para tomar un número y devolverlo en formato de moneda (menos el signo de dólar)
// 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];
}
Una opción simple para la correcta colocación de comas invirtiendo la cadena primero y la expresión regular.
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();
};
Aquí están algunas soluciones, todos pasan el conjunto de pruebas, banco de pruebas y de referencia incluido, si quieres copiar y pegar para probar, probar este Gist .
Método 0 (RegExp)
Base en https://.com/a/14428340/1877620 , pero corríjalo si no hay un punto 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(''.'');
}
}
Método 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(''.'');
};
}
Método 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(''.'');
a[0] = a[0]
.split('''').reverse().join('''')
.replace(//d{3}(?=/d)/g, ''$&,'')
.split('''').reverse().join('''');
return a.join(''.'');
};
}
Método 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.push(''.'');
var i = a.indexOf(''.'') - 3;
while (i > 0 && a[i-1] !== ''-'') {
a.splice(i, 0, '','');
i -= 3;
}
a.pop();
return a.join('''');
};
}
Ejemplo de uso
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));
}
Separador
Si queremos separador de miles personalizado o separador decimal, use replace()
:
123456.78.format(2).replace('','', '' '').replace(''.'', '' '');
Banco de pruebas
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);
Punto de referencia
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();
Como de costumbre, hay varias formas de hacer lo mismo, pero yo evitaría usarlo Number.prototype.toLocaleString
ya que puede devolver diferentes valores según la configuración del usuario.
Tampoco recomiendo que ampliar los Number.prototype
prototipos de objetos nativos sea una mala práctica, ya que puede causar conflictos con el código de otras personas (por ejemplo, bibliotecas / marcos / complementos) y puede no ser compatible con futuras implementaciones / versiones de JavaScript.
Creo que las expresiones regulares son el mejor enfoque para el problema, aquí está mi implementación:
/**
* 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 el 30/08/2010: opción agregada para establecer el número de dígitos decimales. editado en 2011/08/23: opción agregada para establecer el número de dígitos decimales en cero.
El ejemplo de Patrick Desjardins (ex Daok) me funcionó bien. Me porté a coffeescript si alguien está interesado.
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
Encontré esto de: accounting.js . Es muy fácil y se ajusta perfectamente a mi necesidad.
// 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€
Esto puede ser un poco tarde, pero aquí hay un método que hice para que un compañero de trabajo agregue una .toCurrencyString()
función que tenga en cuenta la ubicación a todos los números. La internalización es solo para grupos de números, NO para el signo de moneda: si está generando dólares, utilice "$"
como se suministra, porque $123 4567
en Japón o China es la misma cantidad de USD que $1,234,567
en Estados Unidos. Si está emitiendo euro / etc, cambie el signo de moneda de "$"
.
Declare esto en cualquier lugar de su CABEZA o donde sea necesario, justo antes de que necesite usarlo:
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;
}
¡Entonces has terminado! Use en (number).toCurrencyString()
cualquier lugar que necesite para emitir el número como moneda.
var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
Hay un incorporado function
toFixed enjavascript
var num = new Number(349);
document.write("$" + num.toFixed(2));
No he visto este. Es bastante conciso y 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)
)
Aquí hay una versión con más opciones en la salida final para permitir formatear diferentes monedas en diferentes formatos de localidad.
// 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)
)
Sugiero la clase NumberFormat de la API de visualización de Google .
Puedes hacer algo como esto:
var formatter = new google.visualization.NumberFormat({
prefix: ''$'',
pattern: ''#,###,###.##''
});
formatter.formatValue(1000000); // $ 1,000,000
Espero que ayude.
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 .