Chciałbym sformatować cenę w JavaScript. Chciałbym funkcji, która przyjmuje float
jako argument i zwraca string
sformatowane w ten sposób:
"$ 2,500.00"
Jak najlepiej to zrobić?
Chciałbym sformatować cenę w JavaScript. Chciałbym funkcji, która przyjmuje float
jako argument i zwraca string
sformatowane w ten sposób:
"$ 2,500.00"
Jak najlepiej to zrobić?
Odpowiedzi:
To rozwiązanie jest kompatybilne z każdą główną przeglądarką:
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)
Wystarczy dodać symbol waluty (np. "$" + profits.toFixed(2)
), A otrzymasz kwotę w dolarach.
Jeśli potrzebujesz użyć ,
między każdą cyfrą, możesz użyć tej funkcji:
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>
Używaj go w ten sposób:
(123456789.12345).formatMoney(2, ".", ",");
Jeśli zawsze będziesz używać „.” i „,” możesz pominąć ich wywołanie metody, a metoda domyślnie je dla ciebie.
(123456789.12345).formatMoney(2);
Jeśli w twojej kulturze dwa symbole są odwrócone (tj. Europejczycy) i chcesz użyć wartości domyślnych, po prostu wklej następujące dwie linie w formatMoney
metodzie:
d = d == undefined ? "," : d,
t = t == undefined ? "." : t,
Jeśli możesz użyć nowoczesnej składni ECMAScript (tj. Poprzez Babel), możesz zamiast tego użyć tej prostszej funkcji:
function formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") {
try {
decimalCount = Math.abs(decimalCount);
decimalCount = isNaN(decimalCount) ? 2 : decimalCount;
const negativeSign = amount < 0 ? "-" : "";
let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
let j = (i.length > 3) ? i.length % 3 : 0;
return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "");
} catch (e) {
console.log(e)
}
};
document.getElementById("b").addEventListener("click", event => {
document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>
d
i t
być .
i ,
odpowiednio tak, że nie trzeba określać je za każdym razem. Ponadto zalecam zmodyfikowanie początku return
instrukcji tak, aby brzmiała: return s + '$' + [rest]
w przeciwnym razie nie otrzymasz znaku dolara.
JavaScript ma formatator liczb (część interfejsu API internacjonalizacji).
// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
});
formatter.format(2500); /* $2,500.00 */
Użyj undefined
zamiast pierwszego argumentu ( 'en-US'
w tym przykładzie), aby użyć ustawień regionalnych systemu (ustawień narodowych użytkownika w przypadku, gdy kod działa w przeglądarce). Dalsze objaśnienie kodu regionalnego .
Oto lista kodów walut .
Ostatnia uwaga porównująca to do starszych. toLocaleString
. Oba oferują zasadniczo tę samą funkcjonalność. Jednak toLocaleString w swoich starszych inkarnacjach (pre-Intl) tak naprawdę nie obsługuje ustawień regionalnych : używa ustawień regionalnych systemu. Dlatego upewnij się, że używasz poprawnej wersji ( MDN sugeruje sprawdzenie istnieniaIntl
). Również wydajność obu jest taka sama dla jednego elementu, ale jeśli masz wiele liczb do sformatowania, użycie Intl.NumberFormat
jest ~ 70 razy szybsze. Oto jak używać toLocaleString
:
(2500).toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
}); /* $2,500.00 */
(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); // 12,345.67
Ideą tego rozwiązania jest zastąpienie dopasowanych sekcji pierwszym dopasowaniem i przecinkiem, tj '$&,'
. Dopasowywanie odbywa się przy użyciu metody lookahead . Możesz odczytać wyrażenie „dopasuj liczbę, jeśli następuje po niej ciąg trzech zestawów liczb (jeden lub więcej) i kropka” .
TESTY:
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"
PRÓBNY: http://jsfiddle.net/hAfMM/9571/
Możesz także rozszerzyć prototyp Number
obiektu, aby dodać dodatkowe wsparcie dla dowolnej liczby miejsc po przecinku [0 .. n]
i wielkości grup liczb[0 .. x]
:
/**
* Number.prototype.format(n, x)
*
* @param integer n: length of decimal
* @param integer x: length of sections
*/
Number.prototype.format = function(n, x) {
var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')';
return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,');
};
1234..format(); // "1,234"
12345..format(2); // "12,345.00"
123456.7.format(3, 2); // "12,34,56.700"
123456.789.format(2, 4); // "12,3456.79"
DEMO / TESTY: http://jsfiddle.net/hAfMM/435/
W tej super rozszerzonej wersji możesz ustawić różne typy ograniczników:
/**
* Number.prototype.format(n, x, s, c)
*
* @param integer n: length of decimal
* @param integer x: length of whole part
* @param mixed s: sections delimiter
* @param mixed c: decimal delimiter
*/
Number.prototype.format = function(n, x, s, c) {
var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
num = this.toFixed(Math.max(0, ~~n));
return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
};
12345678.9.format(2, 3, '.', ','); // "12.345.678,90"
123456.789.format(4, 4, ' ', ':'); // "12 3456:7890"
12345678.9.format(0, 3, '-'); // "12-345-679"
DEMO / TESTY: http://jsfiddle.net/hAfMM/612/
.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")
.
Number.prototype.toMoney = (decimal=2) -> @toFixed(decimal).replace /(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,"
\.
z $
(koniec linii), tj this.toFixed(0).replace(/(\d)(?=(\d{3})+$)/g, "$1,")
.
$1,
. Dopasowywanie odbywa się przy użyciu metody lookahead . Możesz odczytać wyrażenie „dopasuj liczbę, jeśli następuje po niej ciąg trzech zestawów liczb (jeden lub więcej) i kropka” .
Spójrz na obiekt JavaScript Number i sprawdź, czy może ci pomóc.
toLocaleString()
sformatuje liczbę przy użyciu separatora tysięcy określonego dla lokalizacji. toFixed()
zaokrągli liczbę do określonej liczby miejsc po przecinku.Aby użyć ich w tym samym czasie, wartość musi zostać zmieniona z powrotem na liczbę, ponieważ oba generują ciąg.
Przykład:
Number((someNumber).toFixed(1)).toLocaleString()
toLocaleString
używająca ustawień regionalnych systemu i nowa (niekompatybilna) pochodząca z interfejsu API ECMAScript Intl. Wyjaśniono tutaj . Ta odpowiedź wydaje się być przeznaczona dla starej wersji.
Poniżej znajduje się kod Patricka Desjardinsa (pseudonim Daok) z dodanymi uwagami i drobnymi zmianami:
/*
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 [/programming/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) : '');
}
a tutaj kilka testów:
//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));
Niewielkie zmiany to:
przeniósł trochę Math.abs(decimals)
do zrobienia tylko wtedy, gdy nie jest NaN
.
decimal_sep
nie może być już pustym ciągiem (pewnego rodzaju separatorem dziesiętnym jest MUSI)
używamy typeof thousands_sep === 'undefined'
zgodnie z sugestią w Jak najlepiej ustalić, czy argument nie jest wysyłany do funkcji JavaScript
(+n || 0)
nie jest potrzebny, ponieważ this
jest Number
obiektem
parseInt
jest wartość bezwzględna części INTEGER liczby. Część INTEGER nie może zaczynać się od ZERO, chyba że jest to po prostu ZERO! I parseInt(0) === 0
ósemkowy lub dziesiętny.
0
jest uważana za ósemkową parseInt
. Ale w tym kodzie NIE MOŻNA parseInt
odbierać 016
jako danych wejściowych (lub jakiejkolwiek innej wartości sformatowanej ósemkowo), ponieważ przekazywany argument parseInt
jest przetwarzany przez Math.abs
funkcję. Nie ma więc możliwości parseInt
otrzymania liczby zaczynającej się od zera, chyba że jest to tylko zero lub 0.nn
(gdzie nn
są miejsca po przecinku). Ale zarówno łańcuchy, jak 0
i 0.nn
łańcuchy zostałyby przekonwertowane parseInt
na zwykłą ZERO, jak się przypuszcza.
account.js to niewielka biblioteka JavaScript do formatowania liczb, pieniędzy i walut.
Jeśli kwota jest liczbą, powiedzmy -123
, to
amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
wyprodukuje ciąg "-$123.00"
.
Oto kompletny przykład działania .
minimumFractionDigits: 0
Oto najlepszy formatyzator pieniędzy js, jaki widziałem:
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) : "");
};
Został ponownie sformatowany i zapożyczony stąd: https://stackoverflow.com/a/149099/751484
Będziesz musiał podać swój własny oznacznik waluty (użyłeś $ powyżej).
Nazwij to w ten sposób (chociaż pamiętaj, że domyślnie argumenty to 2, przecinek i kropka, więc nie musisz podawać żadnych argumentów, jeśli taka jest twoja preferencja):
var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
var
oświadczeniu.
Tutaj są już świetne odpowiedzi. Oto kolejna próba, dla zabawy:
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];
}
I niektóre testy:
formatDollar(45664544.23423) // "$45,664,544.23"
formatDollar(45) // "$45.00"
formatDollar(123) // "$123.00"
formatDollar(7824) // "$7,824.00"
formatDollar(1) // "$1.00"
Edytowane: teraz będzie również obsługiwać liczby ujemne
i = orig.length - i - 1
oddzwanianie. Mimo to o jeden krok mniej w tablicy.
reduce
Metoda została wprowadzona w Ecmascript 1.8 i nie jest obsługiwana w Internet Explorerze 8 i niższych.
Działa dla wszystkich obecnych przeglądarek
Służy toLocaleString
do formatowania waluty w jej reprezentacji wrażliwej na język (przy użyciu kodów walut ISO 4217 ).
(2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2})
Przykładowe fragmenty kodu Rand południowoafrykańskiego dla @avenmore
console.log((2500).toLocaleString("en-ZA", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> R 2 500,00
console.log((2500).toLocaleString("en-GB", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> ZAR 2,500.00
Myślę, że chcesz f.nettotal.value = "$" + showValue.toFixed(2);
Numeral.js - biblioteka js do łatwego formatowania liczb przez @adamwdraper
numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
Ok, na podstawie tego, co powiedziałeś, używam tego:
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;
Jestem otwarty na propozycje ulepszeń (wolę nie uwzględniać YUI tylko po to :-)) Wiem już, że powinienem wykrywać „.” zamiast po prostu używać go jako separatora dziesiętnego ...
Korzystam z biblioteki Globalize (od Microsoft):
To świetny projekt do lokalizowania liczb, walut i dat oraz automatycznego formatowania ich zgodnie z ustawieniami użytkownika! ... i pomimo tego, że powinno to być rozszerzenie jQuery, jest to obecnie w 100% niezależna biblioteka. Proponuję wam wszystkim wypróbować! :)
javascript-number-formatter (wcześniej w Google Code )
#,##0.00
lub z negacją -000.####
.# ##0,00
, #,###.##
, #'###.##
lub dowolnego typu non-numeracji symbolem.#,##,#0.000
lub #,###0.##
wszystkie są ważne.##,###,##.#
lub 0#,#00#.###0#
wszystko w porządku.format( "0.0000", 3.141592)
.(fragment z README)
+1 Jonathanowi M. za dostarczenie oryginalnej metody. Ponieważ jest to jawnie formatator walut, poszedłem dalej i dodałem symbol waluty (domyślnie „$”) do danych wyjściowych i dodałem domyślny przecinek jako separator tysięcy. Jeśli tak naprawdę nie chcesz symbolu waluty (lub separatora tysięcy), po prostu użyj argumentu „” (pusty ciąg) jako argumentu.
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) : "");
};
+n || 0
to jedyna rzecz, która wydaje mi się nieco dziwna (w każdym razie dla mnie).
this
to doskonale przydatna nazwa zmiennej. Przekształcenie go w celu n
zapisania 3 znaków w czasie definicji mogło być konieczne w erze, w której RAM i przepustowość były liczone w KB, ale jest jedynie zaciemniające w erze, w której minimalizator zajmie się tym wszystkim, zanim dotrze do produkcji. Inne sprytne mikrooptymalizacje są przynajmniej dyskusyjne.
Istnieje port javascript funkcji PHP „number_format”.
Uważam, że jest bardzo przydatny, ponieważ jest łatwy w użyciu i rozpoznawalny dla programistów 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;
}
(Blok komentarza do oryginału , zamieszczony poniżej w celu uzyskania przykładów i zaliczek w odpowiednim czasie)
// 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'
Krótsza metoda (do wstawiania spacji, przecinka lub punktu) z wyrażeniem regularnym?
Number.prototype.toCurrencyString=function(){
return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 ');
}
n=12345678.9;
alert(n.toCurrencyString());
Nie widziałem czegoś takiego. Jest dość zwięzły i łatwy do zrozumienia.
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)
)
Oto wersja z większą ilością opcji na końcowym wyjściu, umożliwiającą formatowanie różnych walut w różnych formatach lokalizacyjnych.
// 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)
)
Odpowiedź Patricka Desjardinsa wygląda dobrze, ale wolę mój javascript prosty. Oto funkcja, którą właśnie napisałem, aby pobrać liczbę i zwrócić ją w formacie walutowym (minus znak dolara)
// 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];
}
Główną częścią jest wstawienie separatorów tysiąca, które można wykonać w następujący sposób:
<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)));">
Jest wbudowany w function
toFixed wjavascript
var num = new Number(349);
document.write("$" + num.toFixed(2));
toFixed()
toFixed()
jest funkcją Number
obiektu i nie działałby, var num
gdyby był String
, więc dodatkowy kontekst pomógł mi.
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;
}
Od WillMaster .
Sugeruję klasę NumberFormat z interfejsu API Google Visualization .
Możesz zrobić coś takiego:
var formatter = new google.visualization.NumberFormat({
prefix: '$',
pattern: '#,###,###.##'
});
formatter.formatValue(1000000); // $ 1,000,000
Mam nadzieję, że to pomoże.
To może być trochę za późno, ale oto metoda, którą właśnie opracowałem dla współpracownika, aby dodać funkcję rozpoznawania ustawień regionalnych .toCurrencyString()
do wszystkich liczb. Internalizacja służy wyłącznie do grupowania liczb, a NIE znaku waluty - jeśli wyprowadzasz dolary, użyj tego, "$"
co podano, ponieważ $123 4567
w Japonii lub Chinach jest tyle samo dolarów, co $1,234,567
w USA. Jeśli wypisujesz euro / itp., Zmień znak waluty z "$"
.
Zadeklaruj to w dowolnym miejscu w SZEFIE lub tam, gdzie to konieczne, tuż przed użyciem:
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;
}
To koniec! Użyj (number).toCurrencyString()
wszędzie tam, gdzie chcesz podać liczbę jako walutę.
var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"
Jak zwykle istnieje wiele sposobów na zrobienie tego samego, ale unikałbym używania, Number.prototype.toLocaleString
ponieważ może zwrócić różne wartości w zależności od ustawień użytkownika.
Nie polecam także rozszerzania Number.prototype
- rozszerzanie prototypów obiektów natywnych jest złą praktyką, ponieważ może powodować konflikty z kodem innych osób (np. Bibliotek / frameworków / wtyczek) i może nie być kompatybilne z przyszłymi implementacjami / wersjami JavaScript.
Uważam, że Wyrażenia regularne są najlepszym podejściem do problemu, oto moja implementacja:
/**
* 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);
}
}
edytowany 30.08.2010: dodano opcję ustawiania liczby cyfr dziesiętnych. edytowany w dniu 2011/08/23: dodano opcję ustawienia liczby cyfr dziesiętnych na zero.
Oto niektóre rozwiązania, wszystkie przeszły pakiet testowy, pakiet testowy i test porównawczy, jeśli chcesz skopiować i wkleić w celu przetestowania, wypróbuj This Gist .
Oprzyj na https://stackoverflow.com/a/14428340/1877620 , ale popraw, jeśli nie ma kropki dziesiętnej.
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('.');
}
}
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('.');
};
}
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('.');
};
}
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('');
};
}
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));
}
Jeśli chcemy niestandardowego separatora tysięcy lub separatora dziesiętnego, użyj replace()
:
123456.78.format(2).replace(',', ' ').replace('.', ' ');
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);
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();
Number(value)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
Prosta opcja dla prawidłowego umieszczania przecinków poprzez odwrócenie pierwszego łańcucha i podstawowe wyrażenie regularne.
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();
};
Znalazłem to z: account.js . Jest to bardzo łatwe i idealnie pasuje do moich potrzeb.
// 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€
formatNumber
javascript nie ma wbudowanej funkcji