Question

Je souhaite formater un prix en JavaScript.
J'aimerais une fonction qui prend un float argument et renvoie un string formaté comme ceci:

"$ 2,500.00"

Quelle est la meilleure façon de faire cela?

Était-ce utile?

La solution 12

Ok, d'après 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 & Quot;. & Quot; au lieu de simplement l'utiliser comme séparateur décimal ...

Autres conseils

Number.prototype.toFixed

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 souhaitez utiliser , entre chaque chiffre, vous pouvez utiliser cette fonction:

function formatMoney(number, decPlaces, decSep, thouSep) {
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
decSep = typeof decSep === "undefined" ? "." : decSep;
thouSep = typeof thouSep === "undefined" ? "," : thouSep;
var sign = number < 0 ? "-" : "";
var i = String(parseInt(number = Math.abs(Number(number) || 0).toFixed(decPlaces)));
var j = (j = i.length) > 3 ? j % 3 : 0;

return sign +
	(j ? i.substr(0, j) + thouSep : "") +
	i.substr(j).replace(/(\decSep{3})(?=\decSep)/g, "$1" + thouSep) +
	(decPlaces ? decSep + Math.abs(number - i).toFixed(decPlaces).slice(2) : "");
}

document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

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 vous suffit de coller les deux lignes suivantes dans la formatMoney méthode:

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

Fonction personnalisée (ES6)

Si vous pouvez utiliser la syntaxe ECMAScript moderne (par exemple via Babel), vous pouvez utiliser cette fonction plus simple à la place:

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

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 à la recherche d'un marqueur . . Vous pouvez lire l’expression comme & "; Correspond à un numéro si elle est suivie d’une séquence de trois jeux 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 objet pour ajouter une prise en charge supplémentaire d'un nombre quelconque de décimales [0 .. n] et de la taille des groupes de numéros [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"

DÉMO / TESTS: http://jsfiddle.net/hAfMM/435/

Solution courte très étendue

Dans cette version super é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"

DÉMO / TESTS: http://jsfiddle.net/hAfMM/612/

Intl.numberformat

Javascript dispose d'un formateur de nombre (composant de l'API d'internationalisation).

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

formatter.format(2500); /* $2,500.00 */

violon JS

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 à l’ancien. toLocaleString. Ils offrent tous deux essentiellement les mêmes fonctionnalités. Cependant, toLocaleString dans ses versions antérieures (pré-Intl) ne le fait pas. prend en charge les paramètres régionaux : il utilise les paramètres régionaux du système. Par conséquent, assurez-vous d'utiliser la bonne version ( MDN suggère de vérifier l'existence de Intl ). En outre, les performances des deux sont identiques pour un élément unique , mais si vous devez formater de nombreux nombres, l’utilisation de Intl.NumberFormat est environ 70 fois plus rapide. Voici comment utiliser <=>:

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

Quelques notes sur la prise en charge du navigateur

  • La prise en charge des navigateurs n'est plus un problème avec 97% des utilisateurs aux États-Unis et dans l'Union européenne
  • Dans les autres régions du monde (supporté à 92%), les plus gros auteurs d’aide sont UC Mobile ( restez loin de ça ) et Opera Mini (paralysé par le design)
  • Il existe un shim pour le prendre en charge sur les anciens navigateurs
  • Consultez CanIUse pour plus d'informations

Consultez le code JavaScript Numéro objectez et voyez si cela 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()

Ci-dessous figure le Patrick Desjardins (alias Daok) code avec un peu de commentaires ajoutés 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 modifications mineures sont les suivantes:

  1. a déplacé un peu la Math.abs(decimals) tâche à effectuer uniquement lorsque ce 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 Comment déterminer au mieux si un argument n'est pas envoyé à la fonction JavaScript

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

JS Fiddle

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

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

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

produira la chaîne "-$123.00".

Voici un exemple complet et fonctionnel.

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 identificateur de devise (vous avez utilisé $ ci-dessus).

Appelez-le ainsi (bien que les arguments par défaut soient 2, une virgule, & et un point; vous n'avez donc pas besoin de fournir d'arguments si vous le préférez):

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

Il existe déjà d'excellentes réponses ici. Voici une autre tentative, juste pour le plaisir:

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"

Modifié: désormais, il gérera également les nombres négatifs

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

Alors pourquoi personne n’a-t-il suggéré la chose suivante?

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

Fonctionne pour la plupart / certains navigateurs:

https://developer.mozilla.org/en -FR / docs / Web / JavaScript / Référence / Global_Objects / Number / toLocaleString #Compatibilité_ Browser

Numeral.js - une bibliothèque js facilitant le formatage des nombres par @adamwdraper

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

J'utilise la bibliothèque Globalize (fournie par 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! :)

javascript-number-formter (anciennement à Code Google )

  • Court, rapide, flexible mais autonome. Seulement 75 lignes, y compris les informations de licence MIT, lignes vierges & amp; commentaires.
  • Acceptez le format de numéro standard comme #,##0.00 ou avec la négation -000.####.
  • Acceptez tous les formats de pays tels que # ##0,00, #,###.##, #'###.## ou tout type de symbole non numéroté.
  • Acceptez n'importe quel nombre de groupes de chiffres. #,##,#0.000 ou #,###0.## sont tous valides.
  • Acceptez toute mise en forme redondante / infaillible. ##,###,##.# ou 0#,#00#.###0# sont tous OK.
  • Arrondissement automatique des numéros.
  • Interface simple, fournissez juste mask & amp; valeur comme ceci: format( "0.0000", 3.141592).
  • Inclure un préfixe & amp; suffixe avec le masque

(extrait de son fichier README)

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 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 &. ; crédit le cas échéant)

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

+1 à Jonathan M pour avoir fourni la méthode originale. Comme 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) : "");
};

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());
La réponse de

Patrick Desjardins est satisfaisante, mais je préfère mon langage 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];
}

Il existe un function à corriger dans javascript

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

La partie principale consiste à insérer les milliers de séparateurs, ce qui pourrait se faire comme suit:

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

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

Vous pouvez faire quelque chose comme ceci:

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

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

J'espère que cela vous aidera.

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

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 .

Cela pourrait être un peu tardif, mais voici une méthode que je viens de mettre au point pour permettre à un collègue d’ajouter une fonction .toCurrencyString() tenant compte des paramètres régionaux à tous les nombres. L'internalisation concerne uniquement le groupe de numéros, PAS le symbole monétaire. Si vous exportez des dollars, utilisez "$" tel que fourni, car $123 4567 au Japon ou en Chine correspond au même nombre d'USD que $1,234,567 aux États-Unis. . Si vous éditez euro / etc., Changez le signe monétaire de (number).toCurrencyString().

Déclarez ceci n'importe où dans votre HEAD ou partout où cela est nécessaire, juste avant de 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;
  }

Ensuite, vous avez terminé! Utilisez <=> n’importe où vous devez indiquer 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"

Comme d'habitude, il y a plusieurs façons de faire la même chose, mais j'éviterais d'utiliser Number.prototype.toLocaleString car cela 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 des prototypes d'objets natifs est une mauvaise pratique, car elle peut entraîner des conflits avec le code d'une autre personne (par exemple, bibliothèques / frameworks / plugins) et risque de ne pas être compatible avec les futures implémentations de JavaScript / versions.

Je pense que les expressions régulières constituent la meilleure approche du 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);
    }
}

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

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 Ce résumé .

Méthode 0 (RegExp)

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

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 (diviser en tableau)

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

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

J'ai trouvé ceci dans: 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€ 

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

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top