JavaScript에서 숫자를 통화 문자열 형식으로 지정하려면 어떻게 해야 합니까?

StackOverflow https://stackoverflow.com/questions/149055

  •  02-07-2019
  •  | 
  •  

문제

JavaScript로 가격 형식을 지정하고 싶습니다.
나는 float 인수로 사용하여 다음을 반환합니다. string 다음과 같이 형식화되었습니다.

"$ 2,500.00"

이를 수행하는 가장 좋은 방법은 무엇입니까?

도움이 되었습니까?

해결책 12

좋아, 당신이 말한 것을 바탕으로 나는 이것을 사용하고 있습니다.

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;

나는 개선 제안에 개방적입니다 (나는 이것을하기 위해 Yui를 포함시키지 않는 것을 선호합니다 :-)) 나는 이미 ""를 감지해야한다는 것을 알고 있습니다. 소수 분리기로 사용하는 대신 ...

다른 팁

번호 .Prototype.tofixed

이 솔루션은 모든 주요 브라우저와 호환됩니다.

  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)

통화 기호를 추가하는 것입니다 (예 : "$" + profits.toFixed(2)) 그리고 당신은 당신의 금액을 달러로 가질 것입니다.

사용자 정의 기능

사용이 필요한 경우 , 각 숫자 사이 에서이 기능을 사용할 수 있습니다.

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>

그렇게 사용하십시오.

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

항상 사용하려면 '.' 그리고 ',', 당신은 그것들을 메소드 호출에서 벗어나게 할 수 있으며, 메소드가 기본값을 기본값으로 만듭니다.

(123456789.12345).formatMoney(2);

문화에 두 개의 기호가 뒤집힌 경우 (예 : 유럽인) 기본값을 사용하려면 다음 두 줄에 붙여 넣기 만하면됩니다. formatMoney 방법:

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

사용자 정의 기능 (ES6)

최신 ECMAScript 구문 (즉, 바벨을 통해)을 사용할 수 있다면이 더 간단한 기능을 대신 사용할 수 있습니다.

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>

짧고 빠른 솔루션(어디서나 작동 가능!)

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

이 솔루션의 기본 아이디어는 일치하는 섹션을 첫 번째 일치 및 쉼표로 바꾸는 것입니다. '$&,'.일치는 다음을 사용하여 수행됩니다. 미리보기 접근 방식.다음과 같은 표현을 읽을 수 있습니다. "다음에 세 개의 숫자 세트(하나 이상)와 점이 오는 경우 숫자와 일치합니다.".

테스트:

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"

데모: http://jsfiddle.net/hAfMM/9571/


확장된 짧은 솔루션

프로토타입을 확장할 수도 있습니다. Number 소수 자릿수에 대한 추가 지원을 추가하는 개체 [0 .. n] 숫자 그룹의 크기 [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"

데모/테스트: http://jsfiddle.net/hAfMM/435/


슈퍼 확장된 짧은 솔루션

이에 슈퍼 확장 버전 다양한 구분 기호 유형을 설정할 수 있습니다.

/**
 * 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"

데모/테스트: http://jsfiddle.net/hAfMM/612/

intl.numberformat

JavaScript에는 숫자 Formatter (국제화 API의 일부)가 있습니다.

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

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

JS 바이올린

사용 undefined 첫 번째 논쟁 대신 ('en-US' 예에서) 시스템 로케일 (코드가 브라우저에서 실행되는 경우 사용자 로케일)을 사용합니다.

intl.numberformat vs number.prototype.tolocalestring

이것을 오래된 것과 비교하는 마지막 메모.toLocaleString. 둘 다 본질적으로 동일한 기능을 제공합니다. 그러나 오래된 화신 (pre-Intl)에서 tolocalestring 실제로 로케일을 지원하지 않습니다: 시스템 로케일을 사용합니다. 따라서 올바른 버전을 사용하고 있는지 확인하십시오 (MDN은 존재를 확인할 것을 제안합니다 Intl). 또한 두 가지의 성능은 동일합니다. 하나의 항목이지만 형식에 숫자가 많으면 사용합니다. Intl.NumberFormat ~ 70 배 더 빠릅니다. 사용 방법은 다음과 같습니다 toLocaleString:

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

브라우저 지원에 대한 일부 메모

  • 브라우저 지원은 더 이상 미국/EU에서 97%의 지원으로 문제가되지 않습니다.
  • 세계의 다른 지역 (92% 지원)의 경우 지원 측면에서 가장 큰 범죄자는 UC Mobile입니다 (그것으로부터 멀리 떨어져 있습니다) 및 오페라 미니 (디자인에 의해 크립 핑)
  • 이있다 틈 메우는 나무 이전 브라우저에서 지원합니다
  • 살펴보십시오 사용해도 되나요 더 많은 정보를 위해서

JavaScript를 살펴보십시오 숫자 반대하고 그것이 당신을 도울 수 있는지 확인하십시오.

  • toLocaleString() 위치 별 수천 개의 분리기를 사용하여 숫자를 형식화합니다.
  • toFixed() 숫자를 특정 수의 소수점 자리로 반올림합니다.

이들을 동시에 사용하려면 값은 문자열을 모두 출력하기 때문에 유형을 숫자로 다시 변경해야합니다.

예시:

Number(someNumber.toFixed(1)).toLocaleString()

아래는 다음과 같습니다 Patrick Desjardins (별명 Daok) 약간의 의견이 추가 된 코드와 약간의 변경 사항이 있습니다.

/* 
decimal_sep: character used as deciaml separtor, it defaults to '.' when omitted
thousands_sep: char used as thousands separator, it defaults to ',' when omitted
*/
Number.prototype.toMoney = function(decimals, decimal_sep, thousands_sep)
{ 
   var n = this,
   c = isNaN(decimals) ? 2 : Math.abs(decimals), //if decimal is zero we must take it, it means user does not want to show any decimal
   d = decimal_sep || '.', //if no decimal separator is passed we use the dot as default decimal separator (we MUST use a decimal separator)

   /*
   according to [https://stackoverflow.com/questions/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function]
   the fastest way to check for not defined parameter is to use typeof value === 'undefined' 
   rather than doing value === undefined.
   */   
   t = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, //if you don't want to use a thousands separator you can pass empty string as thousands_sep value

   sign = (n < 0) ? '-' : '',

   //extracting the absolute value of the integer part of the number and converting to string
   i = parseInt(n = Math.abs(n).toFixed(c)) + '', 

   j = ((j = i.length) > 3) ? j % 3 : 0; 
   return sign + (j ? i.substr(0, j) + t : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ''); 
}

그리고 여기에서 몇 가지 테스트 :

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

사소한 변화는 다음과 같습니다.

  1. 조금 움직였습니다 Math.abs(decimals) 그렇지 않은 경우에만 수행됩니다 NaN.

  2. decimal_sep 더 이상 비어있을 수 없습니다 (어떤 종류의 소수점 분리기는 필수입니다)

  3. 우리는 사용 typeof thousands_sep === 'undefined' 제안 된 바와 같이 인수가 JavaScript 함수로 전송되지 않는지 확인하는 방법

  4. (+n || 0) 필요하지 않습니다 this a Number 물체

JS 바이올린

Accounting.js 숫자, 돈 및 통화 형식에 대한 작은 JavaScript 라이브러리입니다.

금액이 숫자 인 경우 -123, 그 다음에

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

문자열을 생성합니다 "-$123.00".

다음은 완전한 작업입니다 예시.

내가 본 최고의 JS Money Formatter는 다음과 같습니다.

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

여기에서 재구성되고 빌려 왔습니다. https://stackoverflow.com/a/149099/751484

자신의 통화 지정자를 제공해야합니다 (위의 $ $ 사용).

이렇게 부릅니다 (Args 기본값은 2, 쉼표 및 기간이되므로 선호하는 경우 Args를 공급할 필요가 없습니다) :

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

여기에는 이미 큰 대답이 있습니다. 재미를 위해 또 다른 시도가 있습니다.

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

그리고 일부 테스트 :

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

편집 : 이제 음수도 처리합니다.

나는 당신이 원하는 것이 있다고 생각합니다 f.nettotal.value = "$" + showValue.toFixed(2);

그렇다면 왜 누구도 다음을 제안하지 않았습니까?

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

대부분의/일부 브라우저에서 작동합니다.

https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/number/tolocalestring#browser_compatibility

숫자 .js - @adamwdraper의 쉬운 번호 서식을위한 JS 라이브러리

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

나는 도서관을 이용한다 세계화 (마이크로소프트에서):

숫자, 통화 및 날짜를 ​​현지화하고 사용자 로케일에 따라 자동으로 올바른 형식으로 지정하는 훌륭한 프로젝트입니다!...jQuery 확장임에도 불구하고 현재는 100% 독립적인 라이브러리입니다.나는 여러분 모두가 그것을 시험해 볼 것을 제안합니다!:)

JavaScript Number-Formatter (이전에 Google 코드)

  • 짧고 빠르며 유연하지만 독립형. MIT 라이센스 정보, 빈 줄 및 댓글을 포함한 75 줄만.
  • 표준 번호 서식을 수락하십시오 #,##0.00 또는 부정 -000.####.
  • 같은 국가 형식을 수락하십시오 # ##0,00, #,###.##, #'###.## 또는 모든 유형의 비 번호부 기호.
  • 숫자 그룹의 수를 수락하십시오. #,##,#0.000 또는 #,###0.## 모두 유효합니다.
  • 중복/바보 형식을 수락하십시오. ##,###,##.# 또는 0#,#00#.###0# 모두 괜찮습니다.
  • 자동 번호 반올림.
  • 간단한 인터페이스, 이와 같은 마스크 및 값을 제공합니다. format( "0.0000", 3.141592).
  • 마스크에 접두사 및 접미사를 포함하십시오

(Readme에서 발췌)

PHP 함수 "number_format"의 JavaScript 포트가 있습니다.

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

(주석 블록에서 원래, 예제 및 크레딧을 위해 아래에 포함).

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

원래 방법을 제공하기 위해 Jonathan M에 +1. 이것은 명시 적으로 통화 형식이기 때문에, 나는 통화 기호 (기본값을 '$'로 추가하여 출력에 추가하고 기본 쉼표를 수천 개의 분리기로 추가했습니다. 실제로 통화 기호 (또는 수천 개의 분리기)를 원하지 않는 경우 ""(빈 문자열)를 논증으로 사용하십시오.

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

정규 표현식으로 짧은 방법 (공간, 쉼표 또는 지점 삽입)?

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

    n=12345678.9;
    alert(n.toCurrencyString());

패트릭 데자르딘'대답은 좋아 보이지만 JavaScript 간단한 것을 선호합니다. 다음은 방금 숫자를 가져 와서 통화 형식으로 반환하기 위해 방금 쓴 기능입니다 (달러 표시를 제외).

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

There is a built-in function toFixed in javascript

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

The main part is inserting the thousand-separators, that could be done like this:

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

I suggest the NumberFormat class from Google Visualization API.

You can do something like this:

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

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

I hope it helps.

Haven't seen this one. It's pretty concise and easy to understand.

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

Here is a version with more options in the final output to allow formatting different currencies in different locality formats.

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

From WillMaster.

This might be a little late, but here's a method I just worked up for a coworker to add a locale-aware .toCurrencyString() function to all numbers. The internalization is for number grouping only, NOT the currency sign - if you're outputting dollars, use "$" as supplied, because $123 4567 in Japan or China is the same number of USD as $1,234,567 is here in the US. If you're outputting euro/etc., then change the currency sign from "$".

Declare this anywhere in your HEAD or wherever necessary, just before you need to use it:

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

Then you're done! Use (number).toCurrencyString() anywhere you need to output the number as currency.

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

As usually, there are multiple ways of doing the same thing but I would avoid using Number.prototype.toLocaleString since it can return different values based on the user settings.

I also don't recommend extending the Number.prototype - extending native objects prototypes is a bad practice since it can cause conflicts with other people code (e.g. libraries/frameworks/plugins) and may not be compatible with future JavaScript implementations/versions.

I believe that Regular Expressions are the best approach for the problem, here is my implementation:

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

edited on 2010/08/30: added option to set number of decimal digits. edited on 2011/08/23: added option to set number of decimal digits to zero.

Here are some solutions, all pass the test suite, test suite and benchmark included, if you want copy and paste to test, try This Gist.

Method 0 (RegExp)

Base on https://stackoverflow.com/a/14428340/1877620, but fix if there is no decimal point.

if (typeof Number.prototype.format === 'undefined') {
    Number.prototype.format = function (precision) {
        if (!isFinite(this)) {
            return this.toString();
        }

        var a = this.toFixed(precision).split('.');
        a[0] = a[0].replace(/\d(?=(\d{3})+$)/g, '$&,');
        return a.join('.');
    }
}

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

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

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

Usage Example

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

Separator

If we want custom thousands separator or decimal separator, use 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);

Benchmark

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

I found this from: accounting.js . Its very easy and perfectly fits my need.

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

A simple option for proper comma placement by reversing the string first and basic regexp.

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

Patrick Desjardins (ex Daok)'s example worked well for me. I ported over to coffeescript if anyone is interested.

Number.prototype.toMoney = (decimals = 2, decimal_separator = ".", thousands_separator = ",") ->
    n = this
    c = if isNaN(decimals) then 2 else Math.abs decimals
    sign = if n < 0 then "-" else ""
    i = parseInt(n = Math.abs(n).toFixed(c)) + ''
    j = if (j = i.length) > 3 then j % 3 else 0
    x = if j then i.substr(0, j) + thousands_separator else ''
    y = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_separator)
    z = if c then decimal_separator + Math.abs(n - i).toFixed(c).slice(2) else ''
    sign + x + y + z
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top