Pregunta ¿Cómo puedo formatear números como la cadena de moneda de dólares en JavaScript?


Me gustaría formatear un precio en JavaScript.
Me gustaría una función que requiera float como argumento y devuelve un string formateado de esta manera:

"$ 2,500.00"

¿Cuál es la mejor manera de hacer esto?


1389


origen


Respuestas:


Puedes usar:

  var profits=2489.8237
  profits.toFixed(3) //returns 2489.824 (round up)
  profits.toFixed(2) //returns 2489.82
  profits.toFixed(7) //returns 2489.8237000 (padding)

Luego puede agregar el signo de '$'.

Si necesita ',' por miles puede usar:

Number.prototype.formatMoney = function(c, d, t){
    var n = this, 
    c = isNaN(c = Math.abs(c)) ? 2 : c, 
    d = d == undefined ? "." : d, 
    t = t == undefined ? "," : t, 
    s = n < 0 ? "-" : "", 
    i = String(parseInt(n = Math.abs(Number(n) || 0).toFixed(c))), 
    j = (j = i.length) > 3 ? j % 3 : 0;
   return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
 };

Y úsala con:

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

Si siempre vas a usar '.' y ',', puede dejarlos fuera de su llamada a método, y el método los predetermina por usted.

(123456789.12345).formatMoney(2);

Si su cultura tiene los dos símbolos volteados (es decir, los europeos), simplemente pegue las siguientes dos líneas en el formatMoney método:

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

1515



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 el primer partido y la coma, es decir '$&,'. La coincidencia se realiza usando enfoque de futuro. Puede leer la expresión como "unir un número si es seguido por 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"

MANIFESTACIÓN:  http://jsfiddle.net/hAfMM/9571/


Solución corta extendida

También puedes extender el prototipo de Number objeto para agregar soporte adicional de cualquier cantidad 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/


Súper solución corta extendida

En esto versión super extendida puedes establecer 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/


1014



Intl.numberformat

Javascript tiene un formateador de números, y es 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 */

JS violín

Algunas notas sobre el soporte del navegador

  • Todos los principales navegadores apoyarlo hoy en día
  • Los mayores delincuentes en términos de soporte son UC Mobile (mantente alejado de eso) y Opera Mini (paralizado por diseño)
  • Hay un calce para apoyarlo en navegadores antiguos
  • Mira esto Puedo usar para más información

Intl.NumberFormat vs Number.prototype.toLocaleString

Una nota final que compara esto con el anterior.toLocaleString. Ambos ofrecen esencialmente la misma funcionalidad. Sin embargo, toLocaleString en sus encarnaciones anteriores (pre-Intl) en realidad no admite configuraciones regionales: usa la configuración regional del sistema. Por lo tanto, para estar seguro de que está utilizando la versión correcta, MDN sugiere verificar la existencia de Intl. Entonces, si necesita verificar Intl de todos modos, ¿por qué no utilizar eso ¿en lugar? Sin embargo, si elige usar la cuña, eso también parches toLocaleString, entonces en ese caso puede usarlo sin ningún problema:

(2500).toLocaleString('en-US', {
  style: 'currency',
  currency: 'USD',
}); /* $2,500.00 */

758



Eche un vistazo al JavaScript Número objetar y ver si te 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 decimales.

Para usar estos al mismo tiempo, el valor debe tener su tipo cambiado de nuevo a un número porque ambos producen una cadena.

Ejemplo:

Number(someNumber.toFixed(1)).toLocaleString()

160



abajo esta el Patrick Desjardins (alias Daok) código con un poco de 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://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) : ''); 
}

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:

  1. movido un poco el Math.abs(decimals) para hacerse solo cuando no es NaN.

  2. decimal_sep ya no puede ser una cadena vacía (es IMPRESCINDIBLE un separador decimal)

  3. usamos typeof thousands_sep === 'undefined' como se sugiere en La mejor forma de determinar si un argumento no se envía a la función de JavaScript

  4. (+n || 0) no es necesario porque this es un Number objeto


157



accounting.js es una pequeña biblioteca de JavaScript para formatear números, dinero y monedas.


120



Aquí está el mejor formateador de dinero js 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) : "");
};

Fue reformateado y tomado de aquí: https://stackoverflow.com/a/149099/751484

Deberá proporcionar su propio designador de moneda (utilizó $ por encima).

Llámalo así (aunque ten en cuenta que los argumentos predeterminados son 2, coma y punto, por lo que no es necesario que proporciones argumentos si así lo prefieres):

var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"

95



Si la cantidad es un número, diga -123, entonces

amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });

producirá la cadena "-$123.00".

Aquí hay un trabajo completo ejemplo.


95



Ya hay algunas buenas respuestas aquí. Aquí hay otro intento, solo 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 también manejará números negativos


70