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?
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>
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 /
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 */
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 */
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()
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:
-
déplacé un peu le
Math.abs(decimals)
à faire seulement quand n'est pasNaN
. -
decimal_sep
ne peut pas être chaîne vide plus (une sorte de séparateur décimal est un MUST) -
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 -
(+n || 0)
n'est pas nécessaire carthis
est unNumber
objet "
de la comptabilité.js est une bibliothèque JavaScript minuscule pour le nombre, l'argent et le formatage de devise.
si le montant est un nombre, dites -123
, puis
amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
produira la chaîne "-3.00"
.
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"
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
je pense que ce que vous voulez est f.nettotal.value = "$" + showValue.toFixed(2);
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:
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...
Chiffre.js - une bibliothèque js pour faciliter le formatage des nombres par @adamwdraper
numeral(23456.789).format('"151900920",0.00'); // = ",456.79"
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! :)
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.
##,###,##.#
ou0#,#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)
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'
+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) : "");
};
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());
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];
}
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.
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)
)
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 .
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"
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)));">
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.
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();
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 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€
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();
};
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