Bagaimana memformat angka sebagai string mata uang?

1847

Saya ingin memformat harga dalam JavaScript. Saya ingin fungsi yang mengambil floatsebagai argumen dan mengembalikan yang stringdiformat seperti ini:

"$ 2,500.00"

Apa cara terbaik untuk melakukan ini?

Daniel Magliola
sumber
8
Tidak ada fungsi formatNumber
bawaan
500
Silakan, untuk siapa pun yang membaca ini di masa depan, jangan tidak menggunakan float ke mata uang toko. Anda akan kehilangan presisi dan data. Anda harus menyimpannya sebagai bilangan bulat sen (atau uang dll.) Dan kemudian mengonversi sebelum menghasilkan.
Philip Whitehouse
8
@ user1308743 Float tidak menyimpan tempat desimal. Ini menyimpan angka menggunakan nilai, basis dan offset. 0,01 sebenarnya tidak dapat diwakili. Lihat: en.wikipedia.org/wiki/Floating_point#Accuracy_problems
Philip Whitehouse
6
@ user1308743: Bayangkan Anda mewakili angka yang sangat besar (katakanlah Anda pria yang beruntung dan itu adalah saldo rekening bank Anda). Apakah Anda benar-benar ingin kehilangan uang karena kekurangan presisi?
ereOn
163
Jadi mengapa tidak ada yang menyarankan yang berikut ini? (2500) .toLocaleString ("en-GB", {style: "currency", mata uang: "GBP", minimumFractionDigits: 2}) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nick Grealy

Jawaban:

1792

Number.prototype.toFixed

Solusi ini kompatibel dengan setiap browser utama:

  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)

Yang Anda butuhkan adalah menambahkan simbol mata uang (mis. "$" + profits.toFixed(2)) Dan Anda akan mendapatkan jumlah Anda dalam dolar.

Fungsi kustom

Jika Anda memerlukan penggunaan ,antara setiap digit, Anda dapat menggunakan fungsi ini:

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>

Gunakan seperti ini:

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

Jika Anda akan selalu menggunakan '.' dan ',', Anda dapat membiarkan mereka keluar dari panggilan metode Anda, dan metode ini akan menetapkan default untuk Anda.

(123456789.12345).formatMoney(2);

Jika budaya Anda memiliki dua simbol dibalik (yaitu orang Eropa) dan Anda ingin menggunakan default, cukup tempelkan dua baris berikut dalam formatMoneymetode:

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

Fungsi khusus (ES6)

Jika Anda dapat menggunakan sintaks ECMAScript modern (yaitu melalui Babel), Anda dapat menggunakan fungsi yang lebih sederhana ini sebagai gantinya:

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>

haykam
sumber
26
pertama-tama, bagus, kode ringkas. Namun, jika Anda orang Amerika, Anda harus mengubah default ddan tmenjadi .dan ,masing - masing sehingga Anda tidak harus menentukannya setiap waktu. juga, saya sarankan untuk memodifikasi awal returnpernyataan untuk membaca return s + '$' + [rest]:, jika tidak, Anda tidak akan mendapatkan tanda dolar.
Jason
744
Tidak yakin mengapa orang berpikir kode ini indah. Itu tidak dapat dipahami. Tampaknya bekerja dengan baik, tetapi itu tidak indah.
usr
86
Apakah fungsi formatMoney ini disalin dari beberapa kode JavaScript yang diperkecil di suatu tempat? Tidak bisakah Anda memposting yang asli? Apa variabel c, d, i, j, n, s, dan t berdiri untuk? Dilihat oleh jumlah upvote dan komentar yang dikirim oleh pos ini, saya dapat mengasumsikan kode ini telah disalin ke situs web produksi di mana-mana ... Selamat mencoba mempertahankan kode jika suatu hari nanti ada bug!
zuallauz
259
"puisi"? Lebih seperti ketidakjelasan. Ini bukan kode golf; gunakan sedikit ruang putih. Nama var yang tepat juga tidak ada salahnya.
keithjgrant
1516

Format Intl

Javascript memiliki pemformat angka (bagian dari API Internasionalisasi).

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

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

Biola JS

Gunakan undefinedmenggantikan argumen pertama ( 'en-US'dalam contoh) untuk menggunakan lokal sistem (pengguna lokal jika kode berjalan di browser). Penjelasan lebih lanjut tentang kode lokal .

Berikut daftar kode mata uang .

Intl.NumberFormat vs Number.prototype.toLocaleString

Catatan akhir membandingkan ini dengan yang lebih tua. toLocaleString. Keduanya pada dasarnya menawarkan fungsionalitas yang sama. Namun, toLocaleString dalam inkarnasinya yang lebih lama (pre-Intl) sebenarnya tidak mendukung lokal : ia menggunakan sistem lokal. Karena itu, pastikan Anda menggunakan versi yang benar ( MDN menyarankan untuk memeriksa keberadaanIntl ). Juga, kinerja keduanya sama untuk satu item, tetapi jika Anda memiliki banyak angka untuk diformat, menggunakan Intl.NumberFormat~ 70 kali lebih cepat. Berikut cara menggunakannya toLocaleString:

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

Beberapa catatan tentang dukungan browser

  • Dukungan browser tidak lagi menjadi masalah saat ini dengan dukungan 97,5% secara global, 98% di AS, dan 99% di UE
  • Ada shim untuk mendukungnya di browser fosil (seperti IE8), jika Anda benar-benar perlu
  • Lihat CanIUse untuk informasi lebih lanjut
aross
sumber
89
JavaScript idomatik ini, solusi sederhana dan elegan persis apa yang saya cari.
Guilhem Soulas
9
Memilih yang satu ini karena itu jawaban sederhana yang sangat bodoh yang bekerja secara asli.
Trasiva
17
Cukup yakin, sebagian besar browser sekarang mendukung hal ini. Ini harus lebih ditingkatkan.
flq
2
Ini adalah jawaban yang bagus dan saya membuatnya bekerja dengan nilai mata uang dinamis jadi jika digunakan di Eropa maka itu berubah menjadi EUR dan menunjukkan tanda euro. Berhasil!
Sprose
3
Ini tahun 2018 dan ini pada dasarnya didukung di mana-mana. Ini seharusnya jawaban yang benar.
sarink
1340

Solusi singkat dan cepat (bekerja di mana-mana!)

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

Gagasan di balik solusi ini adalah mengganti bagian yang cocok dengan pertandingan pertama dan koma, yaitu '$&,'. Pencocokan dilakukan menggunakan pendekatan lookahead . Anda dapat membaca ungkapan sebagai "cocok dengan angka jika diikuti oleh urutan tiga set angka (satu atau lebih) dan satu titik" .

UJI:

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/


Solusi pendek yang diperpanjang

Anda juga dapat memperluas prototipe Numberobjek untuk menambahkan dukungan tambahan dari sejumlah desimal [0 .. n]dan ukuran grup angka [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 / UJI: http://jsfiddle.net/hAfMM/435/


Solusi singkat super diperpanjang

Dalam versi super luas ini Anda dapat mengatur berbagai jenis pembatas:

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

VisioN
sumber
21
Aku benar-benar melangkah lebih jauh: .replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,").
kalisjoshua
4
Versi CoffeeScript dengan VisioN & kalisjoshua regexp dan cara menentukan tempat desimal (sehingga Anda dapat membiarkan default 2 atau menentukan 0 tanpa desimal):Number.prototype.toMoney = (decimal=2) -> @toFixed(decimal).replace /(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,"
Eric Anderson
11
@ Albas Ya, ganti \.dengan $(end of line), yaitu this.toFixed(0).replace(/(\d)(?=(\d{3})+$)/g, "$1,").
VisioN
2
@hanumant Tata bahasa reguler agak rumit di sini, jadi saya sarankan Anda untuk membaca manual tentang ekspresi reguler terlebih dahulu (misalnya di MDN ). Gagasan di baliknya adalah mengganti bagian yang cocok dengan pertandingan pertama dan koma, yaitu $1,. Pencocokan dilakukan menggunakan pendekatan lookahead . Anda dapat membaca ungkapan sebagai "cocok dengan angka jika diikuti oleh urutan tiga set angka (satu atau lebih) dan satu titik" .
VisioN
2
@ JuliendePrabère Tolong beri contoh nomor panjang yang tidak bekerja dengan pendekatan ini.
VisioN
248

Lihatlah objek Nomor JavaScript dan lihat apakah itu dapat membantu Anda.

  • toLocaleString() akan memformat angka menggunakan pemisah ribuan lokasi spesifik.
  • toFixed() akan membulatkan angka ke sejumlah tempat desimal tertentu.

Untuk menggunakan ini pada saat yang sama, nilai harus memiliki jenisnya diubah kembali ke angka karena keduanya menghasilkan string.

Contoh:

Number((someNumber).toFixed(1)).toLocaleString()
17 dari 26
sumber
2
Terima kasih! Berdasarkan ide ini saya bisa membuat yang pendek dan cukup sederhana! (dan dilokalkan) Sangat baik.
Daniel Magliola
7
Sebenarnya kamu bisa. yaitu untuk dolar: '$' + (nilai + 0,001) .toLocaleString (). slice (0, -1)
Zaptree
6
Sepertinya itu akan bagus, tetapi ada sedikit dukungan browser saat ini
acorncom
1
@acorncom Mengapa Anda mengatakan ada "dukungan browser kecil"? Objek Number sudah ada sejak Javascript 1.1. Harap berikan referensi yang mendukung klaim Anda.
Doug S
2
Harus diperhatikan bahwa ada versi lama toLocaleStringyang menggunakan sistem lokal, dan yang baru (tidak kompatibel) yang berasal dari ECMAScript Intl API. Dijelaskan di sini . Jawaban ini sepertinya ditujukan untuk versi lama.
aross
162

Di bawah ini adalah kode Patrick Desjardins (alias Daok) dengan sedikit komentar ditambahkan dan beberapa perubahan kecil:

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

dan di sini beberapa tes:

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

Perubahan kecil adalah:

  1. sedikit bergerak Math.abs(decimals)harus dilakukan hanya ketika tidak NaN.

  2. decimal_sep tidak boleh berupa string kosong lagi (semacam pemisah desimal adalah HARUS)

  3. kami menggunakan typeof thousands_sep === 'undefined'seperti yang disarankan dalam Cara terbaik untuk menentukan apakah argumen tidak dikirim ke fungsi JavaScript

  4. (+n || 0)tidak diperlukan karena thismerupakan Numberobjek

JS Fiddle

Marco Demaio
sumber
8
Anda mungkin ingin menggunakan '10' sebagai radix di parseInt. Jika tidak, angka apa pun yang dimulai dengan '0' akan menggunakan penomoran oktal.
sohtimsso1970
3
@ sohtimsso1970: maaf atas respons yang terlambat, tetapi bisakah Anda menjelaskan lebih banyak lagi? Saya tidak melihat di mana angka dapat ditafsirkan sebagai oktal. The parseIntdisebut pada nilai absolut dari bagian INTEGER dari nomor tersebut. Bagian INTEGER tidak dapat memulai dengan NOL kecuali hanya NOL! Dan parseInt(0) === 0apakah oktal atau desimal.
Marco Demaio
coba, misalnya: parseInt ("016") ... mengembalikan 14, karena parseInt menganggap itu oktal yang disandikan, ketika string dimulai dengan nol.
Tracker1
4
@ Pelacak1: Saya mengerti bahwa nomor yang dimulai dengan 0dianggap oktal oleh parseInt. Tetapi dalam kode ini TIDAK MUNGKIN untuk parseIntmenerima 016sebagai input (atau nilai format oktal lainnya), karena argumen yang diteruskan ke parseIntpertama diproses oleh Math.absfungsi. Jadi tidak ada cara untuk parseIntmenerima angka yang dimulai dengan nol kecuali hanya nol atau 0.nn(di mana nndesimal). Tetapi keduanya 0dan 0.nnstring akan dikonversi oleh parseIntmenjadi NOL polos seperti yang seharusnya.
Marco Demaio
Fungsi ini salah:> (2030) .toMoney (0, '.', ''); <"2 03 0"
Anton P Robul
124

accounting.js adalah pustaka JavaScript kecil untuk pemformatan angka, uang, dan mata uang.

GasheK
sumber
... hanya ingat untuk melewatkan simbol mata uang jika tidak kesalahan dalam IE7 dan IE8, IE9 baik-baik saja
vektor
2
Sepertinya bug IE7 / IE8 sudah diperbaiki.
Mat Schaffer
2
Ini adalah perpustakaan yang hebat, dapat melewati simbol mata uang juga merupakan ide yang baik, karena semua detail mata uang terkandung dalam fungsi panggilan / pengaturan
tunggal
2
Saya suka fakta bahwa Anda dapat melakukan kebalikan - melewati string mata uang yang diformat dan mendapatkan nilai numerik.
Neil Monroe
2
accounting.js sepertinya tidak dikelola akhir-akhir ini. Salah satu percabangan dengan perubahan terbaru adalah github.com/nashdot/accounting-js
RationalDev menyukai GoFundMonica
124

Jika jumlah adalah angka, katakan -123, lalu

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

akan menghasilkan string "-$123.00" .

Inilah contoh kerja yang lengkap .

cs01
sumber
7
Jawaban ini hampir ada untuk saya, tetapi saya perlu dibulatkan ke sen terdekat. Inilah yang saya gunakan number.toLocaleString ('en-GB', {style: 'currency', currency: 'GBP', maksimumFractionDigits: 2});
Nico
Kode di atas tidak membulatkan ke jumlah digit yang Anda inginkan. Lihat contoh dan ketik 1.237 di kotak input.
Daniel Barbalace
3
Tampaknya tidak berfungsi di Safari. Itu hanya mengembalikan nomor sebagai String tanpa format apa pun.
Lance Anderson
1
Wow, ini jawaban yang sangat bagus. Harus di atas.
Ethan
2
Jika karena alasan tertentu Anda tidak ingin sen, Anda dapat mengubah presisi desimal dengan:minimumFractionDigits: 0
Horacio
99

Inilah formatter uang js terbaik yang pernah saya lihat:

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

Itu diformat ulang dan dipinjam dari sini: https://stackoverflow.com/a/149099/751484

Anda harus menyediakan penunjuk mata uang Anda sendiri (Anda menggunakan $ di atas).

Sebut saja seperti ini (walaupun perhatikan bahwa args default ke 2, koma, & titik, jadi Anda tidak perlu memberikan args jika itu pilihan Anda):

var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
Jonathan M
sumber
hati-hati dengan tanda global, i, j
hacklikecrack
6
@hacklikecrack, semua variabel bersifat lokal; mereka ada dalam varpernyataan.
Jonathan M
3
maaf, ya, meskipun Anda sedang mendeklarasikan ulang argumen. Lekukan! ;)
hacklikecrack
Penggunaan variabel nama yang mengerikan!
Serj Sagan
77

Sudah ada beberapa jawaban bagus di sini. Inilah upaya lain, hanya untuk bersenang-senang:

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

Dan beberapa tes:

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

Diedit: sekarang ia akan menangani angka negatif juga

Wayne Burkett
sumber
puisi. cemerlang. Sudahkah Anda mencoba mengurangkanRight () developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… yang seharusnya menghilangkan yang terbalik ()?
Steve
1
@Steve - Anda benar, tetapi Anda harus melakukan sesuatu seperti i = orig.length - i - 1di callback. Tetap saja, satu lagi traversal yang kurang dari array.
Wayne
11
A bukan tentang kompatibilitas: reduceMetode ini diperkenalkan di Ecmascript 1.8, dan tidak didukung di Internet Explorer 8 dan di bawah.
Blaise
Seperti yang dikatakan @Blaise, metode ini tidak akan berfungsi di IE 8 atau di bawahnya.
rsbarro
Ya, tentu saja itu benar. Seperti disebutkan dalam jawaban itu sendiri, ini hanya untuk bersenang-senang. Juga, itu harus menangani angka negatif dengan baik.
Wayne
76

Bekerja untuk semua browser saat ini

Gunakan toLocaleStringuntuk memformat mata uang dalam representasi bahasa yang sensitif (menggunakan kode mata uang ISO 4217 ).

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

Contoh cuplikan kode Rand Afrika Selatan untuk @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

Nick Grealy
sumber
1
Karena argumen 'lokal' dan 'opsi' didukung hanya oleh sejumlah kecil peramban, seperti Chrome 24, IE11 dan Opera 15. Firefox, Safari dan versi lain yang lebih lama masih tidak mendukungnya.
VisioN
3
Setuju, itu belum sepenuhnya didukung di semua browser (belum), tetapi masih merupakan solusi. (Dan bisa dibilang solusi yang paling valid, sebagai forward-nya yang kompatibel dengan browser yang tidak didukung, dan ini merupakan fitur terdokumentasi dari api Javascript.)
Nick Grealy
1
Saya suka ini dan senang itu bekerja dengan pengelompokan digit India.
MSC
7
Ini didukung penuh pada 2017 dan seharusnya menjadi satu-satunya jawaban yang benar
Evgeny
1
Terbaru dan terhebat :) FF69, Chrome76, dll. "R 2 500,00" bukan yang kami gunakan di sini, seharusnya "R 2.500.00", sama dengan en-GB.
Selanjutnya
70

Saya pikir apa yang Anda inginkan f.nettotal.value = "$" + showValue.toFixed(2);

menghancurkan
sumber
@ crush ini berfungsi tetapi tidak lagi membawa perhitungan ke bidang pajak?
Rocco The Taco
11
Setelah Anda menambahkan tanda $ untuk itu, itu bukan lagi angka, tetapi sebuah string.
naksir
Opsi ini tidak menempatkan koma di antara ribuan. :-(
Simon East
29

Numeral.js - perpustakaan js untuk pemformatan angka mudah oleh @adamwdraper

numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
Yarin
sumber
Garpu Numbro tampaknya mendapatkan lebih banyak cinta karena Numeral.js tampaknya ditinggalkan: github.com/foretagsplatsen/numbro
RationalDev suka GoFundMonica
Numeral.js aktif lagi.
adamwdraper
27

Oke, berdasarkan apa yang Anda katakan, saya menggunakan ini:

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;

Saya terbuka untuk saran peningkatan (saya lebih suka untuk tidak memasukkan YUI hanya untuk melakukan ini :-)) Saya sudah tahu saya harus mendeteksi "." alih-alih hanya menggunakannya sebagai pemisah desimal ...

Daniel Magliola
sumber
8
Perhatikan bahwa versi Anda tidak benar dibulatkan menjadi dua angka desimal. Misalnya, 3,706 akan diformat sebagai "£ 3,70", bukan "£ 3,71" seperti yang seharusnya.
Ates Goral
Ya, itu tidak masalah dalam kasus khusus saya, karena jumlah yang saya kerjakan sudah memiliki paling banyak 2 digit. Alasan saya perlu memperbaiki 2 desimal adalah untuk jumlah tanpa desimal atau hanya dengan 1.
Daniel Magliola
26

Saya menggunakan perpustakaan Globalisasi (dari Microsoft):

Ini adalah proyek yang bagus untuk melokalkan angka, mata uang, dan tanggal dan membuatnya secara otomatis diformat dengan cara yang benar sesuai dengan lokal pengguna! ... dan meskipun itu merupakan ekstensi jQuery, saat ini 100% perpustakaan independen. Saya sarankan Anda semua untuk mencobanya! :)

daveoncode
sumber
3
Wow, mengapa ini tidak terunggulkan lagi? Pustaka standar besar untuk semua jenis pemformatan. Parameter pemformatan standar industri dengan globalisasi yang benar. Jawaban bagus !!
pbarranis
Ini masih dianggap tahap alfa, jadi gunakan dengan hati-hati, tetapi penemuan hebat.
Neil Monroe
1
Tidak lagi dalam alfa (atau beta). Ini tampaknya sangat berguna saat kami menunggu Safari memenuhi standar baru dan IE <11 mati.
Guy Schalnat
25

javascript-number-formatter (sebelumnya di Google Code )

  • Pendek, cepat, fleksibel namun mandiri. Hanya 75 baris termasuk info lisensi MIT, baris kosong & komentar.
  • Terima pemformatan angka standar suka #,##0.00atau dengan negasi -000.####.
  • Menerima format negara manapun seperti # ##0,00, #,###.##, #'###.##atau jenis dari simbol non-penomoran.
  • Terima pengelompokan digit angka apa pun. #,##,#0.000atau #,###0.##semuanya valid.
  • Terima pemformatan yang berlebihan / bodoh. ##,###,##.#atau 0#,#00#.###0#semuanya OK.
  • Pembulatan nomor otomatis.
  • Antarmuka yang sederhana, hanya pasokan masker & nilai seperti ini: format( "0.0000", 3.141592).
  • Sertakan awalan & akhiran dengan topeng

(kutipan dari README-nya)

Goodeq
sumber
23

+1 ke Jonathan M untuk memberikan metode asli. Karena ini secara eksplisit formatter mata uang, saya melanjutkan dan menambahkan simbol mata uang (default ke '$') ke output, dan menambahkan koma default sebagai pemisah ribuan. Jika Anda tidak benar-benar menginginkan simbol mata uang (atau ribuan pemisah), cukup gunakan "" (string kosong) sebagai argumen Anda untuk itu.

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) : "");
};
XML
sumber
Var pertama agak aneh, karena variabel-variabel tersebut sudah dideklarasikan dalam deklarasi fungsi. Selain itu, terima kasih!
Rich Bradshaw
2
Kamu benar. Itu kesalahan yang saya bawa dari tulisan asli Jonathan M, di mana mereka semua dirantai sebagai ekspresi tunggal. Itu haruslah penugasan sederhana. Pemasangan.
XML
Dalam hal ini, saya pikir ini mungkin dioptimalkan sebelum waktunya dan harus di refactored agar mudah dibaca. Tetapi tujuan saya adalah untuk menambah kode OP, bukan secara mendasar mengubahnya.
XML
Ini tidak terlalu buruk - satu +n || 0-satunya hal yang tampaknya sedikit aneh (bagi saya).
Rich Bradshaw
2
thisadalah nama variabel yang sangat berguna. Mengubahnya nsehingga Anda dapat menyimpan 3 karakter pada waktu definisi mungkin diperlukan di era ketika RAM dan bandwidth dihitung dalam KB, tetapi hanya membingungkan di era ketika minifier akan mengurus semua itu sebelum mencapai produksi. Optimalisasi mikro pintar lainnya setidaknya bisa diperdebatkan.
XML
22

Ada port javascript dari fungsi PHP "number_format".

Saya merasa sangat berguna karena mudah digunakan dan dikenali untuk pengembang 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 komentar dari aslinya , termasuk di bawah ini untuk contoh & kredit jatuh tempo)

// 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'
DaMayan
sumber
Ini hanya satu fungsi yang benar:> number_format (2030, 0, '.', '') <'2 030' Hebat! Terima kasih
Anton P Robul
21

Metode yang lebih pendek (untuk memasukkan ruang, koma atau titik) dengan ekspresi reguler?

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

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

Belum pernah melihat yang seperti ini. Cukup ringkas dan mudah dimengerti.

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

Ini adalah versi dengan lebih banyak opsi dalam hasil akhir untuk memungkinkan memformat mata uang yang berbeda dalam format lokal yang berbeda.

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

synthet1c
sumber
Cuplikan kode yang hebat, terima kasih. Namun, berhati-hatilah, karena tidak akan berfungsi pada IE karena parameter default tidak didukung, dan "const" dan "let" tidak didukung di <IE11. Gunakan ini untuk memperbaiki: + moneyFormat: fungsi (harga, tanda) {+ jika (tanda!) Tanda = '$'; + potongan = parseFloat (harga) .toFixed (2) .split ('' + + var ii = potongan.length - 3
Charlie Dalsass
Jangan khawatir @CharlieDalsass. Saya akan merekomendasikan menggunakan babel untuk mengkompilasinya ke ES5 untuk kode produksi.
synthet1c
Tetapi bagaimana melakukan mata uang Euro? 1.000,00 Euro?
@YumYumYum Saya menambahkan contoh lengkap dengan lebih banyak opsi pemformatan untuk memungkinkan lebih banyak fleksibilitas.
synthet1c
18

Jawaban Patrick Desjardins terlihat bagus, tetapi saya lebih suka javascript saya yang sederhana. Inilah fungsi yang baru saja saya tulis untuk memasukkan angka dan mengembalikannya dalam format mata uang (dikurangi tanda dolar)

// 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];
}
Tim Saylor
sumber
Saya membutuhkan sesuatu untuk bekerja di browser dan di Node versi lama. Ini bekerja dengan sempurna. Terima kasih
n8jadams
17

Bagian utama adalah memasukkan ribuan pemisah, yang bisa dilakukan seperti ini:

<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)));">
roenving
sumber
Saya mendapatkan output angka yang salah saat memasukkan nilai negatif ke ins1000Sep ().
Peter
16

Ada built-in function toFixed dijavascript

var num = new Number(349);
document.write("$" + num.toFixed(2));
Gerbang
sumber
Jawaban ini terlihat berlebihan. Jawaban Crush sudah didokumentasikantoFixed()
Ian Dunn
3
toFixed()adalah fungsi dari Numberobjek dan tidak akan berfungsi var numjika itu adalah String, jadi konteks tambahan membantu saya.
timborden
15
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;
}

Dari WillMaster .

Bill the Lizard
sumber
Kecil dan sederhana. Terima kasih.
Connor Simpson
1
sederhana, tetapi tidak ada koma untuk 1.000
aron
15

Saya menyarankan kelas NumberFormat dari Google Visualisasi API .

Anda dapat melakukan sesuatu seperti ini:

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

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

Saya harap ini membantu.

juanchopx2
sumber
14

Ini mungkin agak terlambat, tapi inilah metode yang baru saja saya upayakan bagi rekan kerja untuk menambahkan .toCurrencyString()fungsi sadar-lokal ke semua angka. Internalisasi hanya untuk pengelompokan angka, BUKAN tanda mata uang - jika Anda menghasilkan dolar, gunakan "$"sesuai yang disediakan, karena $123 4567di Jepang atau Cina adalah jumlah USD yang sama seperti $1,234,567di AS. Jika Anda menghasilkan euro / dll, maka ubah tanda mata uang dari"$" .

Nyatakan ini di mana saja di KEPALA Anda atau di mana pun diperlukan, tepat sebelum Anda perlu menggunakannya:

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

Lalu kamu selesai! Gunakan di (number).toCurrencyString()mana saja Anda perlu menampilkan nomor sebagai mata uang.

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

Seperti biasanya, ada banyak cara untuk melakukan hal yang sama tetapi saya akan menghindari penggunaan Number.prototype.toLocaleString karena dapat mengembalikan nilai yang berbeda berdasarkan pengaturan pengguna.

Saya juga tidak menyarankan memperpanjang Number.prototype - memperluas prototipe objek asli adalah praktik yang buruk karena dapat menyebabkan konflik dengan kode orang lain (mis. Perpustakaan / kerangka kerja / plugin) dan mungkin tidak kompatibel dengan implementasi / versi JavaScript di masa mendatang.

Saya percaya bahwa Ekspresi Reguler adalah pendekatan terbaik untuk masalah ini, inilah implementasinya:

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

diedit pada 2010/08/30: opsi ditambahkan untuk mengatur jumlah angka desimal. diedit pada 2011/08/23: opsi ditambahkan untuk mengatur jumlah angka desimal menjadi nol.

Miller Medeiros
sumber
Inti dari toLocaleString adalah bahwa hal itu menyesuaikan dengan pengaturan pengguna.
Joseph Lennox
11

Berikut adalah beberapa solusi, semua lulus dari test suite, test suite dan benchmark termasuk, jika Anda ingin copy dan paste untuk menguji, coba This Gist .

Metode 0 (RegExp)

Berbasiskan https://stackoverflow.com/a/14428340/1877620 , tetapi perbaiki jika tidak ada titik desimal.

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

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

Metode 2 (Membagi ke 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('.');
    };
}

Metode 3 (Loop)

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

Contoh Penggunaan

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

Pemisah

Jika kami ingin kustom pemisah ribuan atau pemisah desimal, gunakan replace():

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

Suite uji

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

Tolok ukur

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();
Steely Wing
sumber
Ditingkatkan dari metode Anda 2. ubah dari var a = this.toFixed (presisi) .split ('.'), Ke var multiplier = Math.pow (10, precision + 1), wholeNumber = Math.floor (this * multiplier) ; var a = Math.round (wholeNumber / 10) * 10 / multiplier; if (String (a) .indexOf ('.') <1) {a + = '.00'; } a = String (a) .split ('.'), Jangan gunakan toFixed karena buggy.
vee
console.log (parseFloat ('4.835'). toFixed (2)); > 4.83 console.log (parseFloat ('54 .835 '). ToFixed (2)); > 54.84 console.log (parseFloat ('454.835'). ToFixed (2)); > 454.83 console.log (parseFloat ('8454.835'). ToFixed (2)); > 8454,83 semua desimal nilai ini harus 0,84 bukan 0,83
vee
11

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

Adam Pery
sumber
10

Opsi sederhana untuk penempatan koma yang tepat dengan membalik string terlebih dahulu dan regexp dasar.

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

Saya menemukan ini dari: accounting.js . Sangat mudah dan sangat sesuai dengan kebutuhan saya.

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

Faysal Haque
sumber
$('#price').val( accounting.formatMoney(OOA, { symbol: "€", precision: 2,thousand: ".", decimal :",",format: "%v%s" } ) );- tampilkan 1.000,00 E