42

Is there a built in function of JavaScript to convert a string into a particular locale (Euro in my case)?

E.g. 50.00 should get converted to 50,00 €.

Sebastian Zartner
  • 18,808
  • 10
  • 90
  • 132
Murtaza Mandvi
  • 10,708
  • 23
  • 74
  • 109
  • 1
    'Euro' is not a locale. A locale is e.g. German of Germany or de-DE (language tag as of [Ietf Bcp 47](http://tools.ietf.org/html/bcp47)). – Sebastian Zartner Feb 21 '15 at 22:32

8 Answers8

41

I found a way to do this at this page.

You can you toLocaleString without using toFixed before it. toFixed returns a string, toLocaleString should get a number. But you can pass an options object with toLocaleString, the option minimumFractionDigits could help you with the functionality toFixed has.

50.toLocaleString('de-DE', {
    style: 'currency', 
    currency: 'EUR', 
    minimumFractionDigits: 2 
});

Checkout all the other options you can pass with this function.

Willem de Wit
  • 8,604
  • 9
  • 57
  • 90
  • 1
    Cool, but browser compatibility for options seems low though (IE 11 and Safari not supported) – Jacob van Lingen Mar 14 '14 at 09:20
  • As well as Firefox : Exception: SyntaxError: identifier starts immediately after numeric literal – Darryl Hebbes Sep 07 '16 at 07:58
  • This should be the way to go. The comments above are outdated as ```options``` for ```toLocaleString``` does now work with all browsers (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Browser_compatibility). But you do not need to declare ```minimumFractionDigits``` seperately. It works fine just with ```style``` and ```currency```. – Mirko Brandt Jan 29 '20 at 15:43
24

50.00 is a unit-less value. The best you can do is convert 50.00 to 50,00 and then append the yourself. Therefore, just use Number.toLocaleString().

var i = 50.00;
alert(i.toLocaleString() + ' €'); // alerts '50.00 €' or '50,00 €'

Demo →

Lots of relevant questions:

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 3
    This does not work. After calling toFixed(2) a string is returned. So you're calling toLocaleString() on a string not an integer, which will not include changing '12.34' to '12,34' in French for instance. – user959690 Jun 24 '14 at 20:09
  • 3
    The result of .toFixed() can be parsed back to a float, then it works, e.g. parseFloat((12.3456).toFixed(2)).toLocaleString() – TvdH Jul 02 '14 at 10:20
  • 3
    @TvdH unfortunately that still doesn't work for `50`. – Matt Ball Jul 02 '14 at 13:42
  • @Matt: You are right of course - since 50 and 50.00 is the same to JavaScript. This complicates matters, I came up with this: `var number = 50, scale = 2; console.log((((Math.round(number * Math.pow(10, scale)) * 10) + 1) / Math.pow(10, scale + 1)) .toLocaleString() .slice(0, scale == 0 ? -2 : -1));` – TvdH Jul 02 '14 at 18:14
  • 2
    This does not work out of the box - toFixed() return a string and toLocalString expects a number. Use: `price.toLocaleString(.culture, { minimumFractionDigits: 2, maximumFractionDigits: 2 });` – Morten Holmgaard Sep 08 '14 at 09:43
  • 1
    @MortenHolmgaard That results in an _"Uncaught SyntaxError: Unexpected token ."_ . I think it is the `.culture` part. – Martin Apr 18 '16 at 10:46
15

There are locale related features described within the ECMAScript Internationalization API.

To get the float 50.0 converted to the string 50,00 € (using the 'de-DE' locale) you need to write this:

new Intl.NumberFormat("de-DE", {style: "currency", currency: "EUR"}).format(50.0)

This API is available in all current major browsers.

For more info about the number formatting features of the Internationalization API you should read the article at MDN.

Sebastian Zartner
  • 18,808
  • 10
  • 90
  • 132
8

I am working on an international site which deals with multiple currencies.

I didn't want to deal with setting the Locale every time I wanted to display a currency, so instead I made a prototype which formats the currency to the appropriate locale. It is transparent in its conversions so you can customize it to your needs as well.

Number.prototype.formatMoney = function(moneySymbol, decimalCharacter, thousandsCharacter, decimalPlaces, symbolLocation)
{
    var symbolLocation = (symbolLocation == undefined || symbolLocation < 1 || symbolLocation == "begin")?"begin":"end";
    var decimalPlaces = isNaN(decimalPlaces = Math.abs(decimalPlaces)) ? 2 : decimalPlaces;
    var thisNumber = parseFloat(this, decimalPlaces);
    var decimalCharacter = decimalCharacter == undefined ? "." : decimalCharacter;
    var thousandsCharacter = thousandsCharacter == undefined ? "," : thousandsCharacter;
    //var pm = thisNumber < 0 ? "-" : "";
    var pm = "";
    var pmB = thisNumber < 0 ? "(" : "";
    var pmE = thisNumber < 0 ? ")" : "";
    var i = parseInt(thisNumber = Math.abs(+thisNumber || 0)) + "";
    var j = (j = i.length) > 3 ? j % 3 : 0;
    var retString = pmB;
    retString += ((symbolLocation == "begin")?((moneySymbol)?moneySymbol+"":""):"");
    retString += pm;
    retString += (j ? i.substr(0, j) + thousandsCharacter : "")
    retString += i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousandsCharacter);
    //alert((decimalPlaces ? decimalCharacter + (Math.ceil(Math.abs(thisNumber - i)*Math.pow(10, decimalPlaces))/Math.pow(10, decimalPlaces)).toFixed(decimalPlaces).slice(decimalPlaces) : "") + '\n' + Math.abs(thisNumber - i).toFixed(6));
    retString += (decimalPlaces ? decimalCharacter + (Math.ceil(Math.abs(thisNumber - i).toFixed(6)*Math.pow(10, decimalPlaces))/Math.pow(10, decimalPlaces)).toFixed(decimalPlaces).slice(decimalPlaces) : "");
    retString += ((symbolLocation == "end")?((moneySymbol)?moneySymbol+"":""):"");
    retString += pmE;
    return  retString;
};
Number.prototype.formatMoneyInternational = function(languageCode, inputCode)
{
    var languageCode = languageCode == undefined ? 'en_us' : languageCode;
    var inputCode = inputCode == undefined ? languageCode : inputCode;
    var currencies = {
        'float':    {'symbol':null,         'symbolPosition': 'end',        'decimal':'.',  'comma': ''},       //Float
        //Arabic - Saudi Arabia ?(1025): Sorry, the server does not support this locale 
        //Arabic - Iraq ?(2049): Sorry, the server does not support this locale 
        //Arabic - Egypt ?(3073): Sorry, the server does not support this locale 
        //Arabic - Algeria ?(5121): Sorry, the server does not support this locale 
        'bg':       {'symbol':' BGN',       'symbolPosition': 'end',        'decimal':',',  'comma': ' '},      //Bulgarian 
        'ca':       {'symbol':' €',         'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //Catalan 
        //Chinese - Traditional (1028): Sorry, the server does not support this locale 
        //Chinese - Simplified (2052): Sorry, the server does not support this locale 
        'cs':       {'symbol':' Kc',        'symbolPosition': 'end',        'decimal':',',  'comma': ' '},      //Czech 
        'da':       {'symbol':'kr ',        'symbolPosition': 'begin',      'decimal':',',  'comma': '.'},      //Danish 
        'de':       {'symbol':' €',         'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //German - Germany 
        'de_au':    {'symbol':' €',         'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //German - Austrian 
        'de_lu':    {'symbol':' €',         'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //German - Luxembourg 
        'el':       {'symbol':' €',         'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //Greek 
        'en_us':    {'symbol':'$',          'symbolPosition': 'begin',      'decimal':'.',  'comma': ','},      //English - United States 
        'en_gb':    {'symbol':'£ ',         'symbolPosition': 'begin',      'decimal':'.',  'comma': ','},      //English - United Kingdom 
        'en_au':    {'symbol':'$ ',         'symbolPosition': 'begin',      'decimal':'.',  'comma': ','},      //English - Australia 
        'en_ca':    {'symbol':'$',          'symbolPosition': 'begin',      'decimal':'.',  'comma': ','},      //English - Canadian 
        'en_ie':    {'symbol':'€ ',         'symbolPosition': 'begin',      'decimal':'.',  'comma': ','},      //English - Irish 
        'es_mx':    {'symbol':'$ ',         'symbolPosition': 'begin',      'decimal':'.',  'comma': ','},      //Spanish - Mexico 
        'es':       {'symbol':' €',         'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //Spanish - International 
        'fi':       {'symbol':' €',         'symbolPosition': 'end',        'decimal':',',  'comma': ' '},      //Finnish 
        'fr':       {'symbol':' €',         'symbolPosition': 'end',        'decimal':',',  'comma': ' '},      //French - France 
        'fr_ca':    {'symbol':' $',         'symbolPosition': 'end',        'decimal':',',  'comma': ' '},      //French - Canadian 
        'fr_ch':    {'symbol':'SFr. ',      'symbolPosition': 'begin',      'decimal':'.',  'comma': '\''}, //French - Swiss 
        //Hebrew ?(1037): Sorry, the server does not support this locale 
        'hu':       {'symbol':' Ft',        'symbolPosition': 'end',        'decimal':',',  'comma': ' '},      //Hungarian 
        'it':       {'symbol':'€ ',         'symbolPosition': 'begin',      'decimal':',',  'comma': '.'},      //Italian - Italy 
        'it_ch':    {'symbol':'&#8355; ',       'symbolPosition': 'begin',      'decimal':'.',  'comma': '\''}, //Italian - Swiss 
        'ja':       {'symbol':'¥ ',         'symbolPosition': 'begin',      'decimal':'.',  'comma': '\''}, //Japanese 
        //Korean (1042): Sorry, the server does not support this locale 
        'nl':       {'symbol':'€ ',         'symbolPosition': 'begin',      'decimal':',',  'comma': '.'},      //Dutch - Netherlands 
        'no':       {'symbol':'kr ',        'symbolPosition': 'begin',      'decimal':',',  'comma': ' '},      //Norwegian 
        'pl':       {'symbol':' zl',        'symbolPosition': 'end',        'decimal':',',  'comma': ' '},      //Polish 
        'pt_br':    {'symbol':'R$ ',        'symbolPosition': 'begin',      'decimal':',',  'comma': '.'},      //Portuguese - Brazil 
        'pt':       {'symbol':' €',         'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //Portuguese - Standard 
        'ro':       {'symbol':' lei',       'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //Romanian 
        'ru':       {'symbol':' p.',        'symbolPosition': 'end',        'decimal':',',  'comma': ' '},      //Russian 
        'hr':       {'symbol':' kn',        'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //Croatian 
        'sr':       {'symbol':' Din.',      'symbolPosition': 'end',        'decimal':',',  'comma': '.'},          //Serbian - Latin 
        //'sr': {'symbol':' ???. ', 'symbolPosition': 'end',    'decimal':',',  'comma': '.'},          //Serbian - Cyrillic 
        'sv':       {'symbol':' kr',        'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //Swedish 
        //Thai (1054): Sorry, the server does not support this locale 
        'tr':       {'symbol':' TL',        'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //Turkish 
        'id':       {'symbol':' Rp.',       'symbolPosition': 'begin',      'decimal':' ',  'comma': '.'},      //Indonesian 
        'uk':       {'symbol':' rpH.',      'symbolPosition': 'end',        'decimal':',',  'comma': ' '},          //Ukranian 
        'be':       {'symbol':' p.',        'symbolPosition': 'end',        'decimal':',',  'comma': ' '},      //Belausian 
        'sl':       {'symbol':' SIT',       'symbolPosition': 'end',        'decimal':',',  'comma': '.'},          //Slovenian 
        'et':       {'symbol':' kr',        'symbolPosition': 'end',        'decimal':'.',  'comma': ' '},      //Estonian 
        'lv':       {'symbol':'Ls ',        'symbolPosition': 'begin',      'decimal':',',  'comma': ' '},      //Latvian 
        'lt':       {'symbol':' Lt',        'symbolPosition': 'end',        'decimal':',',  'comma': '.'},      //Lithuanian 
        //Farsi ?(1065): Sorry, the server does not support this locale 
        //Vietnamese (1066): Sorry, the server does not support this locale 
        'af':       {'symbol':'R ',         'symbolPosition': 'begin',      'decimal':'.',  'comma': ','},      //Afrikaans 
        'fo':       {'symbol':'kr ',        'symbolPosition': 'begin',      'decimal':',',  'comma': '.'}       //Faeroese
    };
    var currencyString = this+"";
    if(currencies[languageCode])
    {
        //alert(currencyString.replace(currencies[inputCode].comma, '').replace(currencies[inputCode].decimal, '.').replace(/[^\d\.\,\-]/g, ''));
        var currencyNumber = parseFloat(currencyString.replace(currencies[inputCode].comma, '').replace(currencies[inputCode].decimal, '.').replace(/[^\d\.\,\-]/g, ''));
        return currencyNumber.formatMoney(currencies[languageCode].symbol, currencies[languageCode].decimal, currencies[languageCode].comma, 2, currencies[languageCode].symbolPosition);
    }
    else
    {
        var currencyNumber = parseFloat(currencyString.replace(currencies['en_us'].decimal, '.').replace(currencies['en_us'].comma, '').replace(/[^\d\.\,\-]/g, ''));
        alert('Error: '  + languageCode + ' country code unknown.');
        return currencyNumber.formatMoney(currencies['en_us'].symbol, currencies['en_us'].decimal, currencies['en_us'].comma, 2, currencies['en_us'].symbolPosition);
    }
}
String.prototype.formatMoneyInternational = Number.prototype.formatMoneyInternational;
Luke
  • 435
  • 4
  • 12
7

The accepted answer from Matt Ball is wrong - dunno why nobody haven't noticed. There is no such function as String.toLocaleString() [ref]! Therefore when Number.toFixed() returns String, the consequent toLocaleString() does nothing. So you won't get localized number, just the product of toFixed() function.

WRONG (don't do it like this):

var i = 1234.123;
alert(i.toFixed(2).toLocaleString() + ' €'); // ALWAYS alerts '1234.12 €' (no locale formatting)

Suggestion how to do it right:

You may use jQuery plugin like NumberFormatter.

Jan Peša
  • 6,760
  • 4
  • 27
  • 32
3

Built-in, yes and no. There is Number.toLocaleString() but it is dependent on the system's locale.

However, there are some libraries which have modules for this. MooTools's Locale.Number for example allows you to convert a number into different locales (adding your own locale is trivial).

Locale.use("EU");
var inEuros = (50).formatCurrency(); // € 50,00

jsFiddle Demo


If you want the € sign to be printed after, you can simply create your own locale:

Locale.define('EU-suffix', 'Number', {
    currency: {
        suffix: ' €'
    }
}).inherit('EU', 'Number');
Andrew Moore
  • 93,497
  • 30
  • 163
  • 175
0

Some of the other answers are okay but I would recommend a different library, NumeralJS over Number.toLocaleString because the latter is not supported widely in all browsers (it breaks on even new versions of safari). NumeralJS is really powerful and supports anything you would want to do with converting numbers to strings.

First, set the language (I chose french) and then format it:

numeral.language('fr');
numeral(50.00).format('0.00 $');

Outputs:

"50,00 €"

The website explains it quite well and has tons of examples.

Ben Schenker
  • 869
  • 9
  • 10
0

For javascript use the accounting library http://openexchangerates.github.io/accounting.js/ Then you can do:

// 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
spacebiker
  • 3,777
  • 4
  • 30
  • 49