web-dev-qa-db-fra.com

Comment formater les nombres en dollars en chaîne JavaScript?

Je voudrais formater un prix en JavaScript.
Je voudrais une fonction qui prend une float comme argument et retourne une string au format suivant:

"$ 2,500.00"

Quelle est la meilleure façon de faire cela?

1511
Daniel Magliola

Ok, basé sur ce que vous avez dit, j'utilise ceci:

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;

Je suis ouvert aux suggestions d'amélioration (je préférerais ne pas inclure YUI juste pour faire ceci :-)) Je sais déjà que je devrais détecter le "." au lieu de l'utiliser comme séparateur décimal ...

25
Daniel Magliola

Nombre.prototype.toFixé

Cette solution est compatible avec tous les principaux navigateurs:

  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)

Tout ce dont vous avez besoin est d’ajouter le symbole monétaire (par exemple, "$" + profits.toFixed(2)) et vous aurez votre montant en dollars.

Fonction personnalisée

Si vous avez besoin d'utiliser , entre chaque chiffre, vous pouvez utiliser cette fonction:

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>

Utilisez-le comme suit:

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

Si vous allez toujours utiliser '.' et ',', vous pouvez les laisser en dehors de votre appel de méthode, et la méthode les utilisera par défaut pour vous.

(123456789.12345).formatMoney(2);

Si votre culture comporte les deux symboles retournés (c'est-à-dire les Européens) et que vous souhaitez utiliser les valeurs par défaut, il suffit de coller les deux lignes suivantes dans la méthode formatMoney:

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

Fonction personnalisée (ES6)

Si vous pouvez utiliser la syntaxe ECMAScript moderne (à travers Babel), vous pouvez utiliser cette fonction plus simple:

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>

1596
Patrick Desjardins

Solution courte et rapide (fonctionne partout!)

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

L’idée de cette solution est de remplacer les sections correspondantes par la première correspondance et une virgule, c’est-à-dire '$&,'. La correspondance est effectuée à l'aide de approche anticipée . Vous pouvez lire l’expression sous la forme "correspond à un nombre s’il est suivi d’une séquence de trois ensembles de nombres (un ou plusieurs) et d’un point".

TESTS:

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/


Solution courte étendue

Vous pouvez également étendre le prototype de Number object pour ajouter une prise en charge supplémentaire d’un nombre quelconque de décimales [0 .. n] et de la taille des groupes de nombres [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/TESTS:http://jsfiddle.net/hAfMM/435/


Super solution courte étendue

Dans cette super version étendue vous pouvez définir différents types de délimiteurs:

/**
 * 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/TESTS:http://jsfiddle.net/hAfMM/612/

1136
VisioN

Intl.numberformat

Javascript a un formateur de nombre (partie de l'API d'internationalisation).

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

Utilisez undefined à la place du premier argument ('en-US' dans l'exemple) pour utiliser les paramètres régionaux du système (paramètres régionaux de l'utilisateur dans le cas où le code s'exécute dans un navigateur).

Intl.NumberFormat vs Number.prototype.toLocaleString

Une dernière note comparant ceci à la plus ancienne .toLocaleString. Ils offrent tous deux essentiellement les mêmes fonctionnalités. Cependant, toLocaleString dans ses versions antérieures (pre-Intl) ne prend pas réellement en charge les paramètres régionaux : il utilise les paramètres régionaux du système. Par conséquent, pour vous assurer que vous utilisez la version correcte, MDN suggère de vérifier l'existence de Intl . Donc si vous avez besoin de vérifier quand même pour Intl, pourquoi ne pas utiliser it à la place? Cependant, si vous choisissez d’utiliser le calque, cela corrige également toLocaleString, vous pouvez donc l’utiliser sans problème:

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

Quelques notes sur le support du navigateur

  • La prise en charge des navigateurs n’est plus un problème de nos jours, avec une prise en charge à 97% aux États-Unis et dans l’Union européenne.
  • Pour les autres régions du monde (supporté à 90%), les plus gros délinquants en termes de soutien sont UC Mobile ( restez à l'écart de cela ) et Opera Mini (paralysé par sa conception).
  • Il y a un shim pour le supporter sur les navigateurs plus anciens
  • Jetez un coup d'oeil sur CanIUse pour plus d'informations
931
aross

Jetez un coup d'oeil à l'objet JavaScript Number et voyez s'il peut vous aider.

  • toLocaleString() formatera un nombre en utilisant un séparateur de milliers spécifique à l’emplacement. 
  • toFixed() arrondira le nombre à un nombre spécifique de décimales.

Pour les utiliser en même temps, le type de la valeur doit redevenir un nombre, car ils génèrent tous deux une chaîne. 

Exemple:

Number(someNumber.toFixed(1)).toLocaleString()
186
17 of 26

Vous trouverez ci-dessous le code Patrick Desjardins (alias Daok) avec quelques commentaires et quelques modifications mineures:

/* 
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) : ''); 
}

et voici quelques tests:

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

Les changements mineurs sont les suivants:

  1. déplacé un peu la Math.abs(decimals) à ne faire que quand n'est pas NaN.

  2. decimal_sep ne peut plus être une chaîne vide (une sorte de séparateur décimal est un MUST)

  3. nous utilisons typeof thousands_sep === 'undefined' comme suggéré dans Quelle est la meilleure méthode pour déterminer si un argument n'est pas envoyé à la fonction JavaScript

  4. (+n || 0) n'est pas nécessaire car this est un objet Number

JS Fiddle

159
Marco Demaio

accounting.js est une minuscule bibliothèque JavaScript pour le formatage des nombres, de l'argent et des devises.

122
GasheK

Si le montant est un nombre, dites -123, puis

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

produira la chaîne "-$123.00".

Voici un exemple complet de travail exemple .

107
Daniel Barbalace

Voici le meilleur formateur js money que j'ai vu:

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

Il a été reformaté et emprunté à partir d'ici: https://stackoverflow.com/a/149099/751484

Vous devrez fournir votre propre code de devise (vous avez utilisé $ ci-dessus).

Appelez-le comme ceci (notez bien que les arguments par défaut sont 2, une virgule et un point, vous n'avez donc pas besoin de fournir d'arguments si c'est votre préférence):

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

Il y a déjà quelques bonnes réponses ici. Voici une autre tentative, juste pour le fun:

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

Et quelques tests:

formatDollar(45664544.23423) // "$45,664,544.23"
formatDollar(45) // "$45.00"
formatDollar(123) // "$123.00"
formatDollar(7824) // "$7,824.00"
formatDollar(1) // "$1.00"

Édité: désormais, il gérera les nombres négatifs

72
Wayne Burkett

Je pense que ce que vous voulez, c'est f.nettotal.value = "$" + showValue.toFixed(2);

69
crush

Alors pourquoi personne n'a suggéré ce qui suit? 

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

Fonctionne pour la plupart/certains navigateurs:

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

60
Nick Grealy

J'utilise la bibliothèque Globalize (de Microsoft): 

C'est un excellent projet de localiser les chiffres, les devises et les dates et de les formater automatiquement de la bonne manière en fonction des paramètres régionaux de l'utilisateur! ... et bien qu'il s'agisse d'une extension jQuery, c'est actuellement une bibliothèque 100% indépendante. Je vous suggère à tous de l'essayer! :)

25
daveoncode

Numeral.js - une bibliothèque js pour un formatage facile des nombres par @adamwdraper

numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
25
adamwdraper

javascript-number-formter (anciennement à Google Code )

  • Court, rapide, flexible mais autonome. Seules 75 lignes, y compris les informations de licence MIT, les lignes vierges et les commentaires.
  • Acceptez le formatage de numéro standard comme #,##0.00 ou avec négation -000.####.
  • Acceptez tout format de pays tel que # ##0,00, #,###.##, #'###.## ou tout type de symbole non numéroté.
  • Accepter n'importe quel nombre de groupe de chiffres. #,##,#0.000 ou #,###0.## sont tous valides.
  • Acceptez tout formatage redondant/infaillible. ##,###,##.# ou 0#,#00#.###0# sont tous OK.
  • Arrondissement automatique des chiffres.
  • Interface simple, fournissez juste le masque et la valeur comme ceci: format( "0.0000", 3.141592).
  • Inclure un préfixe et un suffixe avec le masque

(extrait de son fichier README)

23
Goodeq

Il existe un port javascript de la fonction PHP "number_format".

Je le trouve très utile car il est facile à utiliser et reconnaissable par les développeurs 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; 
}

(Bloc de commentaires de l'original , inclus ci-dessous pour des exemples et un crédit si nécessaire)

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

+1 à Jonathan M pour avoir fourni la méthode originale. Etant donné qu’il s’agit explicitement d’un formateur de devise, j’ai ajouté le symbole monétaire («$» par défaut) à la sortie et ajouté une virgule par défaut comme séparateur de milliers. Si vous ne voulez pas réellement de symbole monétaire (ou de séparateur de milliers), utilisez simplement "" (chaîne vide) comme argument.

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

Une méthode plus courte (pour insérer un espace, une virgule ou un point) avec une expression régulière?

    Number.prototype.toCurrencyString=function(){
        return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 ');
    }

    n=12345678.9;
    alert(n.toCurrencyString());
20
Julien de Prabère

functiontoFixed in javascript intégré 

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

Patrick Desjardins 'La réponse a l'air bien, mais je préfère mon javascript simple. Voici une fonction que je viens d'écrire pour saisir un nombre et le renvoyer au format monétaire (moins le signe dollar)

// 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];
}
16
Tim Saylor

Je suggère la classe NumberFormat de API de visualisation Google .

Vous pouvez faire quelque chose comme ça:

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

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

J'espère que ça aide.

15
juanOS

Je n'ai pas vu celui-ci. C'est assez concis et facile à comprendre.

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

Voici une version avec plus d'options dans la sortie finale pour permettre de formater différentes devises dans différents formats de localité.

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

15
synthet1c

C'est peut-être un peu tard, mais voici une méthode que je viens de mettre au point pour qu'un collègue ajoute une fonction .toCurrencyString() tenant compte de la localisation à tous les nombres. L'internalisation concerne uniquement le groupe de numéros, PAS le symbole monétaire. Si vous indiquez des dollars, utilisez "$" tel que fourni, car $123 4567 au Japon ou en Chine correspond au même nombre de dollars que $1,234,567 aux États-Unis. Si vous éditez euro/etc., Changez le symbole monétaire de "$".

Déclarez ceci n'importe où dans votre HEAD ou partout où cela est nécessaire, juste avant de devoir l'utiliser:

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

Alors vous avez terminé! Utilisez (number).toCurrencyString() partout où vous devez entrer le nombre en devise.

var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
14
Jay Dansand

La partie principale est l'insertion des milliers de séparateurs, ce qui pourrait être fait comme ceci:

<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)));">
14
roenving
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 .

14
Bill the Lizard

Voici quelques solutions. Toutes passent avec succès la suite de tests, la suite de tests et le test inclus, si vous voulez copier et coller pour tester, essayez This Gist .

Méthode 0 (RegExp)

Base sur https://stackoverflow.com/a/14428340/1877620 , mais corrigez s'il n'y a pas de point décimal.

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éthode 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éthode 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éthode 3 (boucle)

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

Exemple d'utilisation

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

Séparateur

Si nous voulons un séparateur de milliers ou un séparateur décimal personnalisé, utilisez replace():

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

Suite de tests

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

Référence

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();
11
Steely Wing

Comme d'habitude, il y a plusieurs façons de faire la même chose, mais j'éviterais d'utiliser Number.prototype.toLocaleString car il peut renvoyer des valeurs différentes en fonction des paramètres utilisateur.

Je ne recommande pas non plus d'étendre le Number.prototype - l'extension de prototypes d'objets natifs est une mauvaise pratique, car elle peut entraîner des conflits avec le code d'autres personnes (par exemple, bibliothèques/frameworks/plugins) et peut ne pas être compatible avec les futures implémentations/versions de JavaScript.

Je crois que les expressions régulières sont la meilleure approche pour le problème, voici ma mise en œuvre:

/**
 * 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);
    }
}

édité le 30/08/2010: ajout d'une option permettant de définir le nombre de chiffres décimaux. modifié le 2011/08/23: ajout de l'option permettant de définir le nombre de chiffres décimaux à zéro.

11
Miller Medeiros

J'ai trouvé ceci de: accounting.js . C'est très facile et répond parfaitement à mes besoins.

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

11
Faysal Haque

Une option simple pour le placement correct des virgules en inversant d'abord la chaîne et l'expression rationnelle de base.

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

L’exemple de Patrick Desjardins (ex-Daok) a bien fonctionné pour moi. J'ai reporté sur coffeescript si quelqu'un est intéressé.

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
9
jc00ke

La base de code YUI utilise le formatage suivant:

format: function(nData, oConfig) {
    oConfig = oConfig || {};

    if(!YAHOO.lang.isNumber(nData)) {
        nData *= 1;
    }

    if(YAHOO.lang.isNumber(nData)) {
        var sOutput = nData + "";
        var sDecimalSeparator = (oConfig.decimalSeparator) ? oConfig.decimalSeparator : ".";
        var nDotIndex;

        // Manage decimals
        if(YAHOO.lang.isNumber(oConfig.decimalPlaces)) {
            // Round to the correct decimal place
            var nDecimalPlaces = oConfig.decimalPlaces;
            var nDecimal = Math.pow(10, nDecimalPlaces);
            sOutput = Math.round(nData*nDecimal)/nDecimal + "";
            nDotIndex = sOutput.lastIndexOf(".");

            if(nDecimalPlaces > 0) {
                // Add the decimal separator
                if(nDotIndex < 0) {
                    sOutput += sDecimalSeparator;
                    nDotIndex = sOutput.length-1;
                }
                // Replace the "."
                else if(sDecimalSeparator !== "."){
                    sOutput = sOutput.replace(".",sDecimalSeparator);
                }
                // Add missing zeros
                while((sOutput.length - 1 - nDotIndex) < nDecimalPlaces) {
                    sOutput += "0";
                }
            }
        }

        // Add the thousands separator
        if(oConfig.thousandsSeparator) {
            var sThousandsSeparator = oConfig.thousandsSeparator;
            nDotIndex = sOutput.lastIndexOf(sDecimalSeparator);
            nDotIndex = (nDotIndex > -1) ? nDotIndex : sOutput.length;
            var sNewOutput = sOutput.substring(nDotIndex);
            var nCount = -1;
            for (var i=nDotIndex; i>0; i--) {
                nCount++;
                if ((nCount%3 === 0) && (i !== nDotIndex)) {
                    sNewOutput = sThousandsSeparator + sNewOutput;
                }
                sNewOutput = sOutput.charAt(i-1) + sNewOutput;
            }
            sOutput = sNewOutput;
        }

        // Prepend prefix
        sOutput = (oConfig.prefix) ? oConfig.prefix + sOutput : sOutput;

        // Append suffix
        sOutput = (oConfig.suffix) ? sOutput + oConfig.suffix : sOutput;

        return sOutput;
    }
    // Still not a Number, just return unaltered
    else {
        return nData;
    }
}

il faudrait éditer car la bibliothèque YUI est configurable, comme remplacer oConfig.decimalSeparator par "."

7
albertein

55 réponses en demandent clairement une autre

        function centsToDollaString(x){
          var cents = x + ""
          while(cents.length < 4){
            cents = "0" + cents;
          }
          var dollars = cents.substr(0,cents.length - 2)
          var decimal = cents.substr(cents.length - 2, 2)
          while(dollars.length % 3 != 0){
            dollars = "0" + dollars;
          }
          str = dollars.replace(/(\d{3})(?=\d)/g, "$1" + ",").replace(/^0*(?=.)/,"");
          return "$" + str + "." + decimal;
        }
6
jacob

@tggagne est correct. Ma solution ci-dessous n'est pas bonne en raison de l'arrondi en virgule flottante. Et la fonction toLocaleString ne prend pas en charge certains navigateurs. Je laisserai les commentaires ci-dessous à des fins d'archivage de ce qu'il ne faut PAS faire. :)

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

(Ancienne solution) Utilisez plutôt la solution de Patrick Desjardins.

C'est une solution laconique qui utilise toLocaleString (), prise en charge depuis la version 1.0 de Javascript. Cet exemple désigne la devise en dollars américains, mais peut être basculé en livres en utilisant "GBP" au lieu de "USD".

var formatMoney = function (value) {
    // Convert the value to a floating point number in case it arrives as a string.
    var numeric = parseFloat(value);
    // Specify the local currency.
    return numeric.toLocaleString('USD', { style: 'currency', currency: "USD", minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

Voir https://marcoscaceres.github.io/jsi18n/#localize_currency pour plus de détails.}

6
Ken Palmer

Une fonction pour gérer la sortie de devise, y compris les négatifs .

Exemple de sortie:
5,23 $
- 5,23 $

function formatCurrency(total) {
    var neg = false;
    if(total < 0) {
        neg = true;
        total = Math.abs(total);
    }
    return (neg ? "-$" : '$') + parseFloat(total, 10).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").toString();
}
6
Chad Kuehn

http://code.google.com/p/javascript-number-formatter/ :

  • Court, rapide, flexible mais autonome. Seules 75 lignes, y compris les informations de licence MIT, les lignes vierges et les commentaires.
  • Acceptez le formatage de nombres standard comme #, ## 0.00 ou avec négation -000. ####.
  • Acceptez tous les formats de pays tels que # ## 0,00, #, ###. ##, # '###. ## ou tout autre type de symbole non numéroté.
  • Accepter n'importe quel nombre de groupe de chiffres. #, ##, # 0.000 ou #, ### 0. ## sont tous valides.
  • Acceptez tout formatage redondant/infaillible. ##, ###, ##. # ou 0 #, # 00 #. ### 0 # sont tous OK.
  • Arrondissement automatique des chiffres.
  • Interface simple, il suffit de fournir masque et valeur comme ceci: format ("0.0000", 3.141592)

UPDATE Voici mes utilitaires pp pour les tâches les plus courantes:

var NumUtil = {};

/**
  Petty print 'num' wth exactly 'signif' digits.
  pp(123.45, 2) == "120"
  pp(0.012343, 3) == "0.0123"
  pp(1.2, 3) == "1.20"
*/
NumUtil.pp = function(num, signif) {
    if (typeof(num) !== "number")
        throw 'NumUtil.pp: num is not a number!';
    if (isNaN(num))
        throw 'NumUtil.pp: num is NaN!';
    if (num < 1e-15 || num > 1e15)
        return num;
    var r = Math.log(num)/Math.LN10;
    var dot = Math.floor(r) - (signif-1);
    r = r - Math.floor(r) + (signif-1);
    r = Math.round(Math.exp(r * Math.LN10)).toString();
    if (dot >= 0) {
        for (; dot > 0; dot -= 1)
            r += "0";
        return r;
    } else if (-dot >= r.length) {
        var p = "0.";
        for (; -dot > r.length; dot += 1) {
            p += "0";
        }
        return p+r;
    } else {
        return r.substring(0, r.length + dot) + "." + r.substring(r.length + dot);
    }
}

/** Append leading zeros up to 2 digits. */
NumUtil.align2 = function(v) {
    if (v < 10)
        return "0"+v;
    return ""+v;
}
/** Append leading zeros up to 3 digits. */
NumUtil.align3 = function(v) {
    if (v < 10)
        return "00"+v;
    else if (v < 100)
        return "0"+v;
    return ""+v;
}

NumUtil.integer = {};

/** Round to integer and group by 3 digits. */
NumUtil.integer.pp = function(num) {
    if (typeof(num) !== "number") {
        console.log("%s", new Error().stack);
        throw 'NumUtil.integer.pp: num is not a number!';
    }
    if (isNaN(num))
        throw 'NumUtil.integer.pp: num is NaN!';
    if (num > 1e15)
        return num;
    if (num < 0)
        throw 'Negative num!';
    num = Math.round(num);
    var group = num % 1000;
    var integ = Math.floor(num / 1000);
    if (integ === 0) {
        return group;
    }
    num = NumUtil.align3(group);
    while (true) {
        group = integ % 1000;
        integ = Math.floor(integ / 1000);
        if (integ === 0)
            return group + " " + num;
        num = NumUtil.align3(group) + " " + num;
    }
    return num;
}

NumUtil.currency = {};

/** Round to coins and group by 3 digits. */
NumUtil.currency.pp = function(amount) {
    if (typeof(amount) !== "number")
        throw 'NumUtil.currency.pp: amount is not a number!';
    if (isNaN(amount))
        throw 'NumUtil.currency.pp: amount is NaN!';
    if (amount > 1e15)
        return amount;
    if (amount < 0)
        throw 'Negative amount!';
    if (amount < 1e-2)
        return 0;
    var v = Math.round(amount*100);
    var integ = Math.floor(v / 100);
    var frac = NumUtil.align2(v % 100);
    var group = integ % 1000;
    integ = Math.floor(integ / 1000);
    if (integ === 0) {
        return group + "." + frac;
    }
    amount = NumUtil.align3(group);
    while (true) {
        group = integ % 1000;
        integ = Math.floor(integ / 1000);
        if (integ === 0)
            return group + " " + amount + "." + frac;
        amount = NumUtil.align3(group) + " " + amount;
    }
    return amount;
}
5
gavenkoa

Intl.NumberFormat

var number = 3500;
alert(new Intl.NumberFormat().format(number));
// → "3,500" if in US English locale

ou phpjs.com/functions/number_format

4
iBet7o

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat Exemple: utilisation de paramètres régionaux

Cet exemple montre certaines des variations dans les formats de nombres localisés. Pour obtenir le format de la langue utilisée dans l'interface utilisateur de votre application, assurez-vous de spécifier cette langue (et éventuellement certaines langues de secours) à l'aide de l'argument locales:

numéro var = 123456.789;

// L'allemand utilise une virgule comme séparateur décimal et une période de plusieurs milliers console.log (nouveau format Intl.NumberFormat ('de-DE'). format (nombre)); // → 123.456.789

// Dans la plupart des pays arabophones, l'arabe utilise de vrais chiffres arabes console.log (nouveau format Intl.NumberFormat ('ar-EG'). format (nombre)); // → ٫ ٧٨٩

// L'Inde utilise des séparateurs de milliers/lakh/crore console.log (nouveau Intl.NumberFormat ('en-IN'). Format (nombre));

4
Mohamed.Abdo

Le code de Jonathan M a l'air trop compliqué pour moi, alors je l'ai réécrit et j'ai obtenu environ 30% de FF v30 et 60% sur Chrome v35 boost de vitesse ( http://jsperf.com/number-formating2 ):

Number.prototype.formatNumber = function(decPlaces, thouSeparator, decSeparator) {
    decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
    decSeparator = decSeparator == undefined ? "." : decSeparator;
    thouSeparator = thouSeparator == undefined ? "," : thouSeparator;

    var n = this.toFixed(decPlaces);
    if (decPlaces) {
        var i = n.substr(0, n.length - (decPlaces + 1));
        var j = decSeparator + n.substr(-decPlaces);
    } else {
        i = n;
        j = '';
    }

    function reverse(str) {
        var sr = '';
        for (var l = str.length - 1; l >= 0; l--) {
            sr += str.charAt(l);
        }
        return sr;
    }

    if (parseInt(i)) {
        i = reverse(reverse(i).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator));
    }
    return i+j;
};

Usage:

var sum = 123456789.5698;
var formatted = '$' + sum.formatNumber(2,',','.'); // "$123,456,789.57"
4
Tom

Voici le plus court et le meilleur pour convertir les nombres en format monétaire: 

function toCurrency(amount){
    return amount.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
}

// usage: toCurrency(3939920.3030);

À la vôtre! Anunay

4
Anunay

Cette réponse répond aux critères suivants:

  • Ne dépend pas d'une dépendance externe.
  • Prend en charge la localisation.
  • A des tests/preuves.
  • Utilise des pratiques de codage simples et optimales (pas de regex compliquées, utilise des modèles de codage standard).

Ce code est construit sur des concepts d'autres réponses. Sa vitesse d'exécution devrait être parmi les meilleures publiées ici si cela pose problème.

var decimalCharacter = Number("1.1").toLocaleString().substr(1,1);
var defaultCurrencyMarker = "$";
function formatCurrency(number, currencyMarker) {
    if (typeof number != "number")
        number = parseFloat(number, 10);

    // if NaN is passed in or comes from the parseFloat, set it to 0.
    if (isNaN(number))
        number = 0;

    var sign = number < 0 ? "-" : "";
    number = Math.abs(number);  // so our signage goes before the $ symbol.

    var integral = Math.floor(number);
    var formattedIntegral = integral.toLocaleString();

    // IE returns "##.00" while others return "##"
    formattedIntegral = formattedIntegral.split(decimalCharacter)[0];

    var decimal = Math.round((number - integral) * 100);
    return sign + (currencyMarker || defaultCurrencyMarker) +
        formattedIntegral  +
        decimalCharacter +
        decimal.toString() + (decimal < 10 ? "0" : "");
}

Ces tests ne fonctionnent que sur un ordinateur de paramètres régionaux américains. Cette décision a été prise pour des raisons de simplicité et parce que cela pourrait causer une entrée de mauvaise qualité (mauvaise localisation automatique), ce qui permettrait des problèmes de sortie de mauvaise qualité.

var tests = [
    // [ input, expected result ]
    [123123, "$123,123.00"],    // no decimal
    [123123.123, "$123,123.12"],    // decimal rounded down
    [123123.126, "$123,123.13"],    // decimal rounded up
    [123123.4, "$123,123.40"],  // single decimal
    ["123123", "$123,123.00"],  // repeat subset of the above using string input.
    ["123123.123", "$123,123.12"],
    ["123123.126", "$123,123.13"],
    [-123, "-$123.00"]  // negatives
];

for (var testIndex=0; testIndex < tests.length; testIndex++) {
    var test = tests[testIndex];
    var formatted = formatCurrency(test[0]);
    if (formatted == test[1]) {
        console.log("Test passed, \"" + test[0] + "\" resulted in \"" + formatted + "\"");
    } else {
        console.error("Test failed. Expected \"" + test[1] + "\", got \"" + formatted + "\"");
    }
}
4
Joseph Lennox

Il n'y a pas d'équivalent de "formatNumber" en JavaScript. Vous pouvez l'écrire vous-même ou trouver une bibliothèque qui le fait déjà.

Cela pourrait fonctionner:

function format_currency(v, number_of_decimals, decimal_separator, currency_sign){
  return (isNaN(v)? v : currency_sign + parseInt(v||0).toLocaleString() + decimal_separator + (v*1).toFixed(number_of_decimals).slice(-number_of_decimals));
}

Pas de boucles, pas de regex, pas de tableaux, pas de conditionels exotiques.

3
Daniel Fernandez

Voici une implémentation de mootools 1.2 à partir du code fourni par XMLilley ...

Number.implement('format', function(decPlaces, thouSeparator, decSeparator){
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
decSeparator = decSeparator === undefined ? '.' : decSeparator;
thouSeparator = thouSeparator === undefined ? ',' : thouSeparator;

var num = this,
    sign = num < 0 ? '-' : '',
    i = parseInt(num = Math.abs(+num || 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(num - i).toFixed(decPlaces).slice(2) : '');
});
3
Kirk Bentley

Un moyen plus rapide avec regex?

Number.prototype.toMonetaryString=function(){var n=this.toFixed(2),m;
// var=this.toFixed(2).replace(/\./,','); for comma separator
// with a space for thousands separator
  while ((m=n.replace(/(\d)(\d\d\d)\b/g,'$1 $2'))!=n) n=m; 
  return m;
}
String.prototype.fromMonetaryToNumber=function(s){
  return this.replace(/[^\d-]+/g,'')/100;
}   
3
Julien de Prabère

Approche minimaliste qui répond simplement aux exigences d'origine:

function formatMoney(n) {
    return "$ " + (Math.round(n * 100) / 100).toLocaleString();
}

@Daniel Magliola: Vous avez raison, ce qui précède était une mise en œuvre hâtive et incomplète. Voici l'implémentation corrigée:

function formatMoney(n) {
    return "$ " + n.toLocaleString().split(".")[0] + "."
        + n.toFixed(2).split(".")[1];
}
3
Ates Goral

toLocaleString est bon, mais ne fonctionne pas sur tous les navigateurs. J'utilise habituellement currencyFormatter.js ( - https://osrec.github.io/currencyFormatter.js/ ). Il est plutôt léger et contient toutes les définitions de devise et de paramètres régionaux immédiatement. Il est également performant pour formater des devises au format inhabituel, telles que l’INR (qui regroupe des nombres en lakhs et en crores, etc.). Aussi pas de dépendances!

OSREC.CurrencyFormatter.format(2534234, { currency: 'INR' }); // Returns ₹ 25,34,234.00

OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR' }); // Returns 2.534.234,00 €

OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR', locale: 'fr' }); // Returns 2 534 234,00 €

3
James Eames

Parce que pourquoi ne pas ajouter une autre réponse. Je me suis fortement basé sur la réponse de VisioN.

function format (val) {
  val = (+val).toLocaleString();
  val = (+val).toFixed(2);
  val += "";
  return val.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1" + format.thousands);
}
(function (isUS) {
  format.decimal =   isUS ? "." : ",";
  format.thousands = isUS ? "," : ".";
}(("" + (+(0.00).toLocaleString()).toFixed(2)).indexOf(".") > 0));

J'ai testé avec des entrées:

[   ""
  , "1"
  , "12"
  , "123"
  , "1234"
  , "12345"
  , "123456"
  , "1234567"
  , "12345678"
  , "123456789"
  , "1234567890"
  , ".12"
  , "1.12"
  , "12.12"
  , "123.12"
  , "1234.12"
  , "12345.12"
  , "123456.12"
  , "1234567.12"
  , "12345678.12"
  , "123456789.12"
  , "1234567890.12"
  , "1234567890.123"
  , "1234567890.125"
].forEach(function (item) {
  console.log(format(item));
});

Et obtenu ces résultats:

0.00
1.00
12.00
123.00
1,234.00
12,345.00
123,456.00
1,234,567.00
12,345,678.00
123,456,789.00
1,234,567,890.00
0.12
1.12
12.12
123.12
1,234.12
12,345.12
123,456.12
1,234,567.12
12,345,678.12
123,456,789.12
1,234,567,890.12
1,234,567,890.12
1,234,567,890.13

Juste pour le fun.

2
kalisjoshua

beaucoup de réponses avaient des idées utiles, mais aucune d’entre elles ne pouvait répondre à mes besoins… Donc j’ai utilisé toutes les idées et construit cet exemple:

function Format_Numb( fmt){
    var decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
    if(typeof decSgn==="undefined") decSgn = ".";
    if(typeof kommaSgn==="undefined") kommaSgn= ",";

    var s3digits=/(\d{1,3}(?=(\d{3})+(?=[.]|$))|(?:[.]\d*))/g;
    var dflt_nk="00000000".substring(0,decimals);

    //--------------------------------
    // handler for pattern: "%m"
    var _f_money= function( v_in){
                var v=v_in.toFixed(decimals);
                var add_nk=",00";
                var arr=    v.split(".");
                return     arr[0].toString().replace(s3digits, function ($0) {
                                    return ($0.charAt(0)==".")
                                        ? ((add_nk=""),(kommaSgn + $0.substring(1)))
                                        : ($0 + decSgn);
                        })
                        + (    (decimals > 0)
                                ?    (    kommaSgn
                                        + (
                                            (arr.length > 1)
                                            ? arr[1]
                                            : dflt_nk
                                        )
                                    )
                                :    ""                    
                        );
    }

    // handler for pattern: "%<len>[.<prec>]f"
    var _f_flt= function( v_in,l,prec){
        var v=(typeof prec !== "undefined") ? v_in.toFixed(prec):v_in;
        return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
                ?(Array(l+1).join(" ") + v)
                :v;
    }

    // handler for pattern: "%<len>x"
    var _f_hex= function( v_in,l,flUpper){
        var v=    Math.round(v_in).toString(16);
        if(flUpper)    v=v.toUpperCase();
        return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
                ?(Array(l+1).join("0") + v)
                :v;        
    }

    //...can be extended..., just add the function, f.e.:    var _f_octal= function( v_in,...){
    //--------------------------------

    if( typeof(fmt)!=="undefined"){
        //...can be extended..., just add the char,f.e."O":    MFX -> MFXO
        var rpatt=/(?:%([^%"MFX]*)([MFX]))|(?:"([^"]*)")|("|%%)/gi;
        var _qu=    "\"";
        var _mask_qu=    "\\\"";
        var str=    fmt.toString().replace( rpatt,function($0,$1,$2,$3,$4){
                                var f;
                                if(typeof $1 !== "undefined"){
                                    switch($2.toUpperCase()){
                                        case "M":    f= "_f_money(v)";    break;
                                        case "F":    var    n_Dig0,n_Dig1;
                                                var    re_flt=/^(?:(\d))*(?:[.](\d))*$/;
                                                $1.replace(re_flt,function($0,$1,$2){
                                                    n_Dig0=$1;
                                                    n_Dig1=$2;
                                                });
                                                f= "_f_flt(v," + n_Dig0 + "," + n_Dig1 + ")";    break;
                                        case "X":    var    n_Dig="undefined";
                                                var    re_flt=/^(\d*)$/;
                                                $1.replace(re_flt,function($0){
                                                    if($0!="")n_Dig=$0;
                                                });
                                                f= "_f_hex(v," + n_Dig + "," + ($2=="X") + ")";    break;
                                        //...can be extended..., f.e.:    case "O":
                                    }
                                    return "\"+"+f+"+\"";
                                } else if(typeof $3 !== "undefined"){
                                    return _mask_qu + $3 + _mask_qu;
                                } else {
                                    return ($4==_qu)?_mask_qu:$4.charAt(0);
                                }
                            });
        var cmd=        "return function(v){"
                +        "if(typeof v === \"undefined\")return \"\";"    //null returned as empty string
                +        "if(!v.toFixed)return v.toString();"        //not numb returned as string
                +        "return \"" + str + "\";"
                +    "}";

        //...can be extended..., just add the function name in the 2 places:
        return new Function( "_f_money,_f_flt,_f_hex", cmd)(_f_money,_f_flt,_f_hex);
    }
}

Premièrement, j'avais besoin d'une style C format-chaîne-définition qui devrait être flexible, mais très facile à utiliser et je l'ai défini de la manière suivante; modèles:

%[<len>][.<prec>]f        float, example "%f", "%8.2d", "%.3f"
%m                        money
%[<len>]x                 hexadecimal lower case, example "%x", "%8x"
%[<len>]X                 hexadecimal upper case, example "%X", "%8X"

comme il n’est pas nécessaire de formater d’autres en Euro, j’ai implémenté uniquement "% m" . Mais il est facile d’étendre cette ... Comme en C, la chaîne de formatage est une chaîne contenant les motifs, fe pour l'euro: "% m €" (retourne des chaînes telles que "8.129,33 €")

Outre la flexibilité, j'avais besoin d'une solution très rapide pour le traitement des tables. Cela signifie que lors du traitement de milliers de cellules, le traitement de la chaîne de format ne doit pas être effectué plus d'une fois _. Un appel du type "format (valeur, fmt)" n'est pas acceptable pour moi, mais il doit être scindé en deux étapes:

// var formatter = Format_Numb( "%m €");  
//simple example for Euro...

//   but we use a complex example: 

var formatter = Format_Numb("a%%%3mxx \"zz\"%8.2f°\"  >0x%8X<");

// formatter is now a function, which can be used more than once (this is an example, that can be tested:) 

var v1= formatter( 1897654.8198344); 

var v2= formatter( 4.2); 

... (and thousands of rows)

Également pour la performance, _f_money inclut la regexp;

Troisièmement, un appel du type "format (valeur, fmt)" n’est pas acceptable, car: Même s’il devrait être possible de formater différentes collections d’objets (par exemple, des cellules d’une colonne) avec différents masques, je ne souhaite pas avoir quelque chose à gérer les chaînes de format au moment du traitement. À ce stade, je veux seulement utiliser le formatage, comme dans

for (var cellule dans les cellules) {do_something (cell.col.formatter ( cell.value)); }

Quel format - peut-être est-il défini dans un ini, dans un xml pour chaque colonne ou ailleurs ..., mais analyser et définir les formats ou traiter avec internationalizaton est traité totalement ailleurs , et là je veux assigner le formateur à la collection sans penser aux problèmes de performances:

col.formatter = Format_Numb (_getFormatForColumn (...));

Quatrièmement, je voulais une solution "tolérante", passant ainsi f.e. une chaîne au lieu d'un nombre doit simplement renvoyer la chaîne, mais "null" doit renvoyer une chaîne vide.

(Le formatage "% 4.2f" ne doit pas non plus couper quelque chose si la valeur est trop grande.)

Et le dernier mais non le moindre - il devrait être lisible et facilement extensible SANS avoir d’effets sur les performances .... Par exemple, si quelqu'un a besoin de "valeurs octales", veuillez vous reporter aux lignes avec ". ..peut être étendu ... "- Je pense que cela devrait être une tâche très facile.

Mon objectif général est la performance. Chaque "routine de traitement" (fe _f_money) peut être encapsulée de manière optimisée ou échangée avec d'autres idées de ce fil ou d'autres threads sans modification des "routines de préparation" (chaînes de format d'analyse et création des fonctions), qui ne doivent être traitées qu'une seule fois sens ne sont pas aussi critiques en termes de performances que les appels de conversion de milliers de numéros.

Pour tous, qui préfèrent les méthodes de nombres:

Number.prototype.format_euro=( function(formatter){
    return function(){ return formatter(this); }})
    (Format_Numb( "%m €"));

var v_euro= (8192.3282).format_euro(); //results: 8.192,33 €

Number.prototype.format_hex= (function(formatter){
    return function(){ return formatter(this); }})
    (Format_Numb( "%4x"));

var v_hex= (4.3282).format_hex();

Bien que j'ai testé quelque chose, il peut y avoir beaucoup de bugs dans le code. Ce n'est donc pas un module prêt à l'emploi, mais juste une idée et un point de départ pour les non-experts en js comme moi ... Le code contient de nombreuses et peu d'idées modifiées à partir de beaucoup de messages stackoverflow; désolé, je ne peux pas tous les citer, mais merci à tous les experts.

2
user2807653

Je voulais une solution javascript Vanilla qui renvoie automatiquement la partie décimale.

function formatDollar(amount) {
    var dollar = Number(amount).toLocaleString("us", "currency");
    //decimals
    var arrAmount = dollar.split(".");
    if (arrAmount.length==2) {
        var decimal = arrAmount[1];
        if (decimal.length==1) {
            arrAmount[1] += "0";
        }
    }
    if (arrAmount.length==1) {
        arrAmount.Push("00");
    }

    return "$" + arrAmount.join(".");
}


console.log(formatDollar("1812.2");
2
Nicolas Giszpenc

J'ai eu du mal à trouver une bibliothèque simple pour travailler avec la date et la monnaie. J'ai donc créé le mien: https://github.com/dericeira/slimFormatter.js

Aussi simple que cela:

var number = slimFormatter.currency(2000.54);
2
Daniel Campos

Coffeescript pour la réponse populaire de Patrick ci-dessus:

Number::formatMoney = (decimalPlaces, decimalChar, thousandsChar) ->  
  n = this  
  c = decimalPlaces  
  d = decimalChar  
  t = thousandsChar  
  c = (if isNaN(c = Math.abs(c)) then 2 else c)  
  d = (if d is undefined then "." else d)  
  t = (if t is undefined then "," else t)  
  s = (if n < 0 then "-" else "")  
  i = parseInt(n = Math.abs(+n or 0).toFixed(c)) + ""  
  j = (if (j = i.length) > 3 then j % 3 else 0)  
  s + (if j then i.substr(0, j) + t else "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (if c then d + Math.abs(n - i).toFixed(c).slice(2) else "")  
2
DanielEli
String.prototype.toPrice = function () {
    var v;
    if (/^\d+(,\d+)$/.test(this))
        v = this.replace(/,/, '.');
    else if (/^\d+((,\d{3})*(\.\d+)?)?$/.test(this))
        v = this.replace(/,/g, "");
    else if (/^\d+((.\d{3})*(,\d+)?)?$/.test(this))
        v = this.replace(/\./g, "").replace(/,/, ".");
    var x = parseFloat(v).toFixed(2).toString().split("."),
    x1 = x[0],
    x2 = ((x.length == 2) ? "." + x[1] : ".00"),
    exp = /^([0-9]+)(\d{3})/;
    while (exp.test(x1))
        x1 = x1.replace(exp, "$1" + "," + "$2");
    return x1 + x2;
}

alert("123123".toPrice()); //123,123.00
alert("123123,316".toPrice()); //123,123.32
alert("12,312,313.33213".toPrice()); //12,312,313.33
alert("123.312.321,32132".toPrice()); //123,312,321.32
2
Ebubekir Dirican

J'aime la réponse la plus courte de VisionN, sauf lorsque je dois la modifier pour un nombre sans virgule décimale (123 $ au lieu de 123,00 $), cela ne fonctionne pas. Par conséquent, au lieu d'un copier/coller rapide, je dois déchiffrer la syntaxe arcane de l'expression rationnelle JavaScript.

Voici la solution originale

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

Je vais le faire un peu plus longtemps:

var re = /\d(?=(\d{3})+\.)/g;
var subst = '$&,';
n.toFixed(2).replace(re, subst);

Re part here (recherche partie dans string replace) signifie

  1. Trouver tous les chiffres (\d)
  2. Suivi de (?= ...) (lookahead)
  3. Un ou plusieurs groupes (...)+
  4. D'exactement 3 chiffres (\d{3})
  5. Se terminant par un point (\.)
  6. Faites-le pour toutes les occurrences (g)

Subst partie signifie ici

  1. Chaque fois qu'il y a une correspondance, remplacez-la par elle-même ($&) suivie d'une virgule.

Comme nous utilisons string.replace, tous les autres textes de la chaîne restent identiques et seuls les chiffres trouvés (suivis de 3,6,9, etc., autres chiffres) ont une virgule supplémentaire.

Donc, dans un nombre 1234567.89 chiffres 1 et 4 remplissez la condition ( 1 23 4 567.89) et sont remplacés par " 1, " et " 4, "résultant en 1 234 567,89.

Si nous n’avons pas besoin de la virgule décimale en dollars (c’est-à-dire 123 $ au lieu de 123,00 $), nous pouvons modifier l’expression rationnelle de la manière suivante:

var re2 = /\d(?=(\d{3})+$)/g;

Il s'appuie sur la fin de la ligne ($) au lieu d'un point (\.) et l'expression finale sera (notez également toFixed(0)):

n.toFixed(0).replace(/\d(?=(\d{3})+$)/g, '$&,');

Cette expression donnera

1234567.89 -> 1,234,567

De même, au lieu de la fin de la ligne ($) dans l'expression régulière ci-dessus, vous pouvez également opter pour une limite de Word (\b).

Mes excuses à l’avance si j’ai mal interprété une partie de la gestion des regex.

2
mp31415

Je veux contribuer avec ceci:

function toMoney(amount) {
    neg = amount.charAt(0);
    amount= amount.replace(/\D/g, '');
    amount= amount.replace(/\./g  , '');
    amount= amount.replace(/\-/g, '');

    var numAmount = new Number(amount); 
    amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
        return i > 0 && c !== "," && (a.length - i) % 3 === 0 ? "." + c : c;
    });

    if(neg == '-')
        return neg+amount;
    else
        return amount;
}

Cela vous permet de convertir des nombres dans une zone de texte où vous ne pouvez que mettre des nombres (considérez ce scénario)

Ceci va nettoyer une zone de texte où seuls supposent être des nombres même si vous collez une chaîne avec des chiffres et des lettres ou n'importe quel caractère

<html>
<head>
<script language=="Javascript">
function isNumber(evt) {    
    var theEvent = evt || window.event;
    var key = theEvent.keyCode || theEvent.which;
    key = String.fromCharCode(key);
    if (key.length == 0) return;
    var regex = /^[0-9\-\b]+$/;
    if (!regex.test(key)) {
        theEvent.returnValue = false;
        if (theEvent.preventDefault) theEvent.preventDefault();
    }
}
function toMoney(amount) {
    neg = amount.charAt(0);
    amount= amount.replace(/\D/g, '');
    amount= amount.replace(/\./g  , '');
    amount= amount.replace(/\-/g, '');

    var numAmount = new Number(amount); 
    amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
        return i > 0 && c !== "," && (a.length - i) % 3 === 0 ? "." + c : c;
    });

    if(neg == '-')
        return neg+amount;
    else
        return amount;
}
function clearText(inTxt, newTxt, outTxt) {
    inTxt = inTxt.trim();
    newTxt = newTxt.trim();
    if(inTxt == '' || inTxt == newTxt) 
        return outTxt;

    return inTxt;   
}

function fillText(inTxt, outTxt) {
    inTxt = inTxt.trim();
    if(inTxt != '') 
        outTxt = inTxt;

    return outTxt;
}
</script>
</head>
<body>
$ <input name=reca2 id=reca2 type=text value="0" onFocus="this.value = clearText(this.value, '0', '');" onblur="this.value = fillText(this.value, '0'); this.value = toMoney(this.value);" onKeyPress="isNumber(event);" style="width:80px;" />
</body>
</html>
function getMoney(A){
    var a = new Number(A);
    var b = a.toFixed(2); //get 12345678.90
    a = parseInt(a); // get 12345678
    b = (b-a).toPrecision(2); //get 0.90
    b = parseFloat(b).toFixed(2); //in case we get 0.0, we pad it out to 0.00
    a = a.toLocaleString();//put in commas - IE also puts in .00, so we'll get 12,345,678.00
    //if IE (our number ends in .00)
    if(a < 1 && a.lastIndexOf('.00') == (a.length - 3))
    {
        a=a.substr(0, a.length-3); //delete the .00
    }
    return a+b.substr(1);//remove the 0 from b, then return a + b = 12,345,678.90
}
alert(getMoney(12345678.9));

Cela fonctionne dans FF et IE

1

Number(value)
        .toFixed(2)
        .replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")

1
Adam Pery

Il y a déjà de bonnes réponses. Voici une tentative simple pour le plaisir:

function currencyFormat(no) {
  var ar = (+no).toFixed(2).split('.');
  return [
      numberFormat(ar[0]|0),
      '.', 
      ar[1]
  ].join('');
}


function numberFormat(no) {
  var str = no + '';
  var ar = [];
  var i  = str.length -1;

  while( i >= 0 ) {
    ar.Push( (str[i-2]||'') + (str[i-1]|| '')+ (str[i]|| ''));
    i= i-3;
  }
  return ar.reverse().join(',');  
}

La course des exemples

console.log(
  currencyFormat(1),
  currencyFormat(1200),
  currencyFormat(123),
  currencyFormat(9870000),
  currencyFormat(12345),
  currencyFormat(123456.232)
)
1
rab

Voici un formateur simple dans Vanilla JS:

function numberFormatter (num) {
        console.log(num)
    var wholeAndDecimal = String(num.toFixed(2)).split(".");
    console.log(wholeAndDecimal)
    var reversedWholeNumber = Array.from(wholeAndDecimal[0]).reverse();
    var formattedOutput = [];

    reversedWholeNumber.forEach( (digit, index) => {
        formattedOutput.Push(digit);
        if ((index + 1) % 3 === 0 && index < reversedWholeNumber.length - 1) {
            formattedOutput.Push(",");
        }
    })

    formattedOutput = formattedOutput.reverse().join('') + "." + wholeAndDecimal[1];

    return formattedOutput;

}
1
meetalexjohnson

J'aime ça simple:

function formatPriceUSD(price) {
    var strPrice = price.toFixed(2).toString();
    var a = strPrice.split('');

    if (price > 1000000000)
        a.splice(a.length - 12, 0, ',');

    if (price > 1000000)
        a.splice(a.length - 9, 0, ',');

    if (price > 1000)
        a.splice(a.length - 6, 0, ',');

    return '$' + a.join("");
}
1
Tomas Kubes

Parce que chaque problème mérite une solution en une seule ligne:

Number.prototype.formatCurrency = function() { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, '$1,') : t + '.' + c; }, '$'); }

C'est assez facile à changer pour différents endroits, changez simplement '$ 1' en '$ 1'. et '.' pour ',' échanger, et. en chiffres et le symbole monétaire peut être changé en changeant le '$' à la fin.

Ou, si vous avez ES6, vous pouvez simplement déclarer la fonction avec les valeurs par défaut:

Number.prototype.formatCurrency = function(thou = ',', dec = '.', sym = '$') { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, '$1' + thou) : t + dec + c; }, sym); }

console.log((4215.57).formatCurrency())
$4,215.57
console.log((4216635.57).formatCurrency('.', ','))
$4.216.635,57
console.log((4216635.57).formatCurrency('.', ',', "\u20AC"))
€4.216.635,57

Oh, ça marche aussi pour les nombres négatifs:

console.log((-6635.574).formatCurrency('.', ',', "\u20AC"))
-€6.635,57
console.log((-1066.507).formatCurrency())
-$1,066.51

Et bien sûr, vous n'avez pas besoin d'un symbole monétaire

console.log((1234.586).formatCurrency(',','.',''))
1,234.59
console.log((-7890123.456).formatCurrency(',','.',''))
-7,890,123.46
console.log((1237890.456).formatCurrency('.',',',''))
1.237.890,46
0
Nick

Voilà le mien...

function thousandCommas(num) {
  num = num.toString().split('.');
  var ints = num[0].split('').reverse();
  for (var out=[],len=ints.length,i=0; i < len; i++) {
    if (i > 0 && (i % 3) === 0) out.Push(',');
    out.Push(ints[i]);
  }
  out = out.reverse() && out.join('');
  if (num.length === 2) out += '.' + num[1];
  return out;
}
0
mendezcode