Comment puis-je formater des nombres en dollars chaîne de devises en JavaScript?

je voudrais formater un prix en JavaScript.

Je voudrais une fonction qui prend un float comme argument et retourne un string formaté comme ceci:

"$ 2,500.00"

Quelle est la meilleure façon de faire cela?

1422
demandé sur Daniel Magliola 2008-09-29 19:00:28

30 réponses

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

il suffit d'ajouter le symbole de la devise (par exemple "$" + profits.toFixed(2) ) et vous aurez votre montant en dollars.

fonction sur mesure

Si vous avez besoin de l'utilisation de , 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, "" + 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>

l'Utiliser de la sorte:

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

si vous allez toujours utiliser".'et ',', vous pouvez les laisser hors de votre appel de méthode, et la méthode par défaut pour vous.

(123456789.12345).formatMoney(2);

si votre culture a les deux symboles inversés (c.-à-d. européens) et que vous souhaitez utiliser les valeurs par défaut, il suffit de coller sur les deux lignes suivantes dans la méthode formatMoney :

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

fonction sur mesure (ES6)

si vous pouvez utiliser la syntaxe moderne D'ECMAScript (i.e. par 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, "" + 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>
1535
répondu haykam 2018-09-12 12:23:51

solution courte et rapide (fonctionne partout!)

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

l'idée derrière cette solution est de remplacer les sections appariées par first match et virgule, i.e. '$&,' . L'appariement se fait en utilisant lookahead approach . Vous pouvez lire l'expression "correspond à un nombre si elle est suivie par une séquence de trois séries (une ou plusieurs) et un point" .

essais:

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 /


Étendu à court de solution

vous pouvez également étendre le prototype de Number objet pour ajouter un support supplémentaire de n'importe quel nombre de décimales [0 .. n] et la taille des groupes de nombre [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 /


Super-longue à court de solution

dans cette super extended version 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 /

1057
répondu VisioN 2018-06-28 14:18:15

Intl.numéro du formulaire

Javascript a un formatteur de nombre (faisant 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); /* ,500.00 */

js fiddle

Quelques notes sur la prise en charge du navigateur

  • tous les principaux navigateurs support it today
  • les plus grands contrevenants en termes de les supports sont UC Mobile ( stay away from that ) et Opera Mini (infirme de conception)
  • Il ya un shim pour le prendre en charge sur les navigateurs plus anciens
  • regarder CanIUse pour plus d'info

Intl.Numéro de série vs numéro.prototype.toLocaleString

une note finale comparant ceci à l'ancien . toLocaleString . Ils offrent tous les deux essentiellement la même fonctionnalité. Cependant, toLocaleString dans ses anciennes incarnations (pre-Intl) ne supporte pas réellement les locales : il utilise la locale système. Par conséquent, pour être sûr que vous utilisez la bonne version, MDN suggère de vérifier l'existence de Intl . Donc, si vous avez besoin de vérifier pour Intl de toute façon, pourquoi ne pas utiliser it à la place? Cependant, si vous choisissez d'utiliser le shim, cela patches aussi toLocaleString , donc, dans ce cas vous pouvez l'utiliser sans aucun tracas:

(2500).toLocaleString('en-US', {
  style: 'currency',
  currency: 'USD',
}); /* ,500.00 */
810
répondu aross 2018-08-14 12:16:00

regardez l'objet JavaScript Number et voyez s'il peut vous aider.

  • toLocaleString() sera le format d'un numéro à l'aide de l'emplacement spécifique de séparateur des milliers.
  • toFixed() arrondit le nombre à un nombre de décimales.

pour les utiliser en même temps, la valeur doit être ramenée à un nombre parce qu'ils produisent tous les deux une chaîne.

exemple:

Number(someNumber.toFixed(1)).toLocaleString()
167
répondu 17 of 26 2016-11-22 12:48:21

ci-dessous est le Patrick Desjardins (alias Daok) code avec un peu de commentaires ajoutés et quelques changements mineurs:

/* 
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 [/q/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function-10908/"" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ''); 
}

et ici quelques essais:

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

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

  2. decimal_sep ne peut pas être chaîne vide plus (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

  5. "
157
répondu Marco Demaio 2017-05-23 12:03:09

de la comptabilité.js est une bibliothèque JavaScript minuscule pour le nombre, l'argent et le formatage de devise.

120
répondu GasheK 2018-04-11 15:03:50

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

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

produira la chaîne "-3.00" .

voici un exemple complet de .

97
répondu cs01 2018-04-11 15:05:25

voici le meilleur formateurjs 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, "" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};

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

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

appelez cela comme ceci (bien que notez que l'args par défaut à 2, virgule, & period, Donc vous n'avez pas besoin de fournir des args si c'est votre préférence):

var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // ",543.76"
96
répondu Jonathan M 2017-05-23 11:47:36

il y a déjà de grandes 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 essais:

formatDollar(45664544.23423) // ",664,544.23"
formatDollar(45) // ".00"
formatDollar(123) // "3.00"
formatDollar(7824) // ",824.00"
formatDollar(1) // ".00"

Édité: maintenant, il va gérer les nombres négatifs ainsi

70
répondu Wayne Burkett 2016-12-07 06:35:05

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

67
répondu crush 2012-02-16 20:42:09

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

55
répondu Nick Grealy 2013-09-25 01:42:45

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 simplement l'utiliser comme séparateur décimal...

24
répondu Daniel Magliola 2008-09-29 15:22:33

Chiffre.js - une bibliothèque js pour faciliter le formatage des nombres par @adamwdraper

numeral(23456.789).format('"151900920",0.00'); // = ",456.79"
24
répondu Yarin 2016-02-27 14:45:23

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

c'est un grand projet de localiser des nombres, des devises et des dates et de les faire formater automatiquement de la bonne façon selon la localisation de l'utilisateur! ...et en dépit de ça devrait être une extension jQuery, c'est actuellement une bibliothèque 100% indépendante. Je vous suggère à tous de l'essayer! :)

24
répondu daveoncode 2018-04-11 15:06:08

javascript-number-formatter (anciennement à Google Code )

  • Court, rapide, à la fois souple et autonome. seulement 75 lignes, y compris les informations sur la licence du MIT, les lignes vierges et les commentaires.
  • accepter le formatage de numéro standard comme #,##0.00 ou avec négation -000.#### .
  • Accepter n'importe quel pays de format comme # ##0,00 , #,###.## , #'###.## ou tout autre symbole non numéroté.
  • accepte tous les numéros de groupes numériques. #,##,#0.000 ou #,###0.## sont tous valables.
  • accepter tout formatage redondant / infaillible. ##,###,##.# ou 0#,#00#.###0# sont tous OK.
  • calcul automatique.
  • interface Simple, juste fournir le masque et la valeur comme ceci: format( "0.0000", 3.141592) .
  • ajouter un préfixe et suffixe avec le masque

(extrait de son README)

22
répondu Goodeq 2016-08-03 17:47:52

il y a un port javascript de la fonction PHP"number_format".

je le trouve très utile car il est facile à utiliser et reconnaissable pour 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+'');
        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 les exemples et le crédit où dû)

// 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'
20
répondu DaMayan 2014-09-18 20:25:55

+1 à Jonathan M pour avoir fourni la méthode originale. Puisqu'il s'agit explicitement d'un formatteur de devise, j'ai ajouté le symbole de devise (par défaut à '$') à la sortie, et j'ai ajouté une virgule par défaut comme séparateur de milliers. Si vous ne voulez pas réellement un symbole de devise (ou un séparateur de milliers), utilisez juste "" (chaîne vide) comme argument pour cela.

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, "" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};
20
répondu XML 2014-10-21 04:01:57

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

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

    n=12345678.9;
    alert(n.toCurrencyString());
19
répondu Julien de Prabère 2012-01-04 12:46:12

Patrick Desjardins " la réponse semble bonne, mais je préfère mon javascript simple. Voici une fonction que je viens d'écrire pour prendre un nombre Dans et le retourner dans le format de la devise (moins le signe du 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];
}
15
répondu Tim Saylor 2017-05-23 12:10:54

Il est un construit-dans function toFixed dans javascript

var num = new Number(349);
document.write("$" + num.toFixed(2));
15
répondu Gate 2012-08-22 19:10:51

je vous propose 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 aidera.

14
répondu juanchopx2 2012-10-02 21:25:21

N'ont 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)
)
14
répondu synthet1c 2017-06-08 05:41:08
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;
}

À Partir De WillMaster .

13
répondu Bill the Lizard 2008-09-29 15:16:57

c'est peut-être un peu tard, Mais voici une méthode que je viens d'élaborer pour un collaborateur pour ajouter une fonction .toCurrencyString() sensible à la localisation à tous les nombres. L'internalisation est pour le groupement de nombres seulement, pas le signe de devise - si vous produisez des dollars, utilisez "$" comme fourni, parce que 3 4567 au Japon ou en Chine est le même nombre de USD que ,234,567 est ici aux États-Unis. Si vous produisez euro / etc., puis changer le signe de devise de "$" .

déclarez ceci n'importe où dans votre tête ou partout où nécessaire, juste avant que vous devez 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 c'est fini! Utilisez (number).toCurrencyString() n'importe où vous avez besoin de produire le nombre comme devise.

var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "3,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
13
répondu Jay Dansand 2018-04-11 15:07:49

la partie principale est l'insertion des Mille-séparateurs, 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,",");
  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)));">
12
répondu roenving 2008-09-29 15:18:23

comme d'habitude, il y a plusieurs façons de faire la même chose, mais je voudrais éviter d'utiliser Number.prototype.toLocaleString car il peut retourner différentes valeurs basées sur les paramètres de l'utilisateur.

Je ne recommande pas non plus d'étendre les prototypes Number.prototype - extension des objets natifs est une mauvaise pratique car elle peut causer des conflits avec le code d'autres personnes (par exemple bibliothèques/cadres/plugins) et peut ne pas être compatible avec de futures implémentations/versions 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 [], middle [] and decimal digits []

    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é sur 2010/08/30: ajout d'une option pour définir le nombre de chiffres après la virgule. édité le 23/08/2011: option ajoutée pour mettre le nombre de décimales à zéro.

10
répondu Miller Medeiros 2011-08-23 15:33:34

voici quelques solutions, tous passent la suite d'essai, la suite d'essai et le benchmark inclus, si vous voulez copier et Coller pour tester, essayez ce Gist .

Method 0 (RegExp)

Base sur https://stackoverflow.com/a/14428340/1877620 , mais corriger 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('.');
    };
}

La 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 personnalisé ou un séparateur décimal, utilisez replace() :

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

Test suite

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

de Référence", 1519140920"
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();

10
répondu Steely Wing 2017-05-23 12:34:59

j'ai trouvé ceci de: comptabilité.js . Son très facile et répond parfaitement à mon besoin.

// Default usage:
accounting.formatMoney(12345678); // ,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€ 
10
répondu Faysal Haque 2017-06-07 08:01:36

une option simple pour le placement correct de la virgule en inversant la première chaîne et le regexp 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, ',' ).reverse();
};
9
répondu troy 2011-12-02 23:58:39

L'exemple de Patrick Desjardins (ex Daok) a bien fonctionné pour moi. Je suis passé en coffee-script 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, "" + thousands_separator)
    z = if c then decimal_separator + Math.abs(n - i).toFixed(c).slice(2) else ''
    sign + x + y + z
8
répondu jc00ke 2012-02-09 12:04:59