Complete list of all different Intl.NumberFormats - javascript

I'm looking for a complete list of all the different Intl.NumberFormats.
The Intl.NumberFormat page shows 3 different formats.
ja-JP -> "¥123,457"
de-DE -> 123.456,79 €
en-IN -> 1,23,000
Is this all? Or is there more?

Intl was introduced here https://hacks.mozilla.org/2014/12/introducing-the-javascript-internationalization-api/ with these takeaways:
There's no official list, since "The api is best-effort"
By default, browsers accepts ALL correctly formatted codes (BCP 47 is mentioned and then finds the best fit
You might specify lookup only to disable the best fit algorithm, and then you could get a list of all countries and language codes and that way run through all combinations for a specific browser on a specific OS with a specific list of installed languages but I guess that's not what you want to hear if you're building a web project. But you might want to make use of supportedLocalesOf to have something locally relevant to choose from.
Under the hood browsers typically use ICU or similar
tl;dr: So if you send in your best guess at a valid locale, the best fit algorithm will get you something usable!
Valid locale?
According to the documentation and my earlier research, the Intl javascript API expects you to format your locale codes according to BCP 47.

Go through this it has all the format available
Some of popular locales:
pl_PL = 1 205,34 zł
en_US = $1,205.34
en_GB = £1,205.34
en_IE = €1,205.34
de_DE = 1.205,34 €
fr_FR = 1 205,34 €
br_FR = € 1 205,34
ja_JP = ¥1,205
pt_TL = 1 205,34 US$
fr_CA = 1 205,34 $
en_CA = $1,205.34
And for All possible locales visit:
https://gist.github.com/ncreated/9934896

en-IE = €1,205.34
ro-MD = 1.205,34 MDL
br = ¤ 1 205,34
en-GY = $1,205
es-GT = Q1,205.34
All Locale Visit : https://gist.github.com/raushankrjha/d1c7e35cf87e69aa8b4208a8171a8416

All different formats available worldwide.
$c = '{
"en_EN": "$100,000.00",
"de_DE": "100.000,00 $",
"af_AF": "$ 100,000.00",
"am_AM": "US$100,000.00",
"ar_AR": "١٠٠٬٠٠٠٫٠٠ US$",
"bn_BN": "১,০০,০০০.০০US$",
"bg_BG": "100000,00 щ.д.",
"ca_CA": "100.000,00 USD",
"cs_CS": "100 000,00 US$",
"nl_NL": "US$ 100.000,00",
"et_ET": "100 000,00 $",
"fr_FR": "100 000,00 $US",
"he_HE": "‏100,000.00 $",
"hi_HI": "$1,00,000.00",
"it_IT": "100.000,00 US$",
"nb_NB": "USD 100 000,00",
"ms_MS": "USD100,000.00",
"id_ID": "US$100.000,00",
"pl_PL": "100 000,00 USD"}';

Related

Adding language or Contributing to ECMAScript Internationalization API localization

How do I contribute Internationalization API languages or add language ? In Mongolia we use different number formatting and date format, also when I need to format number in Mongolian I need to create custom function to do it. And I want to use Intl API, because
const formattedNumber = Intl.NumberFormat('mn-MN', { notation: "compact" })
is better than writing function below
function formatNumber (number) {
if(number > 1000000000) return number / 1000000000 + " тэрбум"
///and so on
return number;
}
I did little research and all the languages and variants are registered here and subtags are listed in the Unicode CLDR Project. But when I use mn-Cyrl or any other Mongolian locale it returns default en-US string. So I am wondering if I am able to contribute to Intl API localization.
I see, you might need this. it's official
proposal-intl-numberformat-v3

Why would Intl.NumberFormat with options be outputting a euro symbol on the left when the docs say it should be on the right?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat#Using_options
The example in the docs:
var number = 123456.789;
// request a currency format
console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// → 123.456,79 €
My output in Node 10:
> new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(123456.789)
'€ 123,456.79'
Euro symbol on the right in the docs. On the left when I actually run the code. Do I have to set a locale or something? I'm in the US. But I'm actually asking for de-DE format, seems like that should override my locale. Running the exact code from the example made no difference.
Very likely you Node does not have full locale support for Intl, only English (small-icu)
See https://nodejs.org/api/intl.html#intl_detecting_internationalization_support
Try the "To check for support for a non-English locale" part.
Solution (if you have small-icu, the most likely case)
You can (of course) recompile (as the page linked above recommends)
But you can use a shortcut, it might work and save you some time
Start node and use process.versions.icu
(in my case is '62.1', for node v10.15.3)
Download the matching ICU sources (which contain the data file)
The URL is something like http://download.icu-project.org/files/icu4c/<version>/icu4c-<version>-src.tgz.
In my case http://download.icu-project.org/files/icu4c/62.1/icu4c-62_1-src.tgz
Unpack the ICU sources and find the icu data file. In my case the data file is at icu/source/data/in/icudt62l.dat. But the location might be different in other ICU versions (although I doubt, it is not impossible :-)
Set NODE_ICU_DATA to point to the date file.
Either export NODE_ICU_DATA=<icu_data_path>/icudt62l.dat (define the variable) or env NODE_ICU_DATA=<icu_data_path>/icudt62l.dat node (define + run node)
You would probably want to move the data file in a more "stable" place and remove ICU the sources
It is pretty lame that Node does not provide versions with full ICU support ready to download.
Or at least archived ICU data files matching the Node releases, so that we don't have to go through all this digging.

Is there a way to get the decimal and thousands separator in ECMAscript Internationalization API?

I'm trying to use the new Javascript internationalization API, and would like to know if there is a way to get the decimal and thousands (grouping) separator for a Intl.NumberFormat instance?
There is a resolvedOptions method on the object, but that does not provide the symbols.
In case anybody's wondering, then for en-US, these would be a comma , and period ., such as in 1,000.00.
If nothing else, as a trick solution (that doesn't pass the Turkey Test; see comment), you can use the output of toLocaleString() to determine information about number formatting in a locale. For the current locale, for example:
var decimalSeparator =
(12345.6789).toLocaleString().match(/345(.*)67/)[1];
var thousandSeparator =
(12345.6789).toLocaleString().match(/12(.*)345/)[1];
var numberOfDecimals =
(12345.6789).toLocaleString().match(/345(\D*)(\d+)$/)[2].length;
The same trick can be used for currency formatting, using e.g. (12345.6789).toLocaleString("en-GB", { style: "currency" }).
I'm afraid ECMA-402 standard does not define the API that let you access separators. There is also another problem - at the moment the adoption of ECMA-402 is not as wide as we wish.
Therefore for the time being, if I were you I would look to something like CLDR JSON bindings or iLib which apparently provides these information through LocaleInfo's getDecimalSeparator() and getGroupingSeparator() functions.
BTW. iLib seems to use CLDR as a source of information.

Detecting number format culture settings

I have a webpage that needs to take numeric input, this part is easy enough with some combination of parseFloat, isNaN and (for displaying the values back to the user) toFixed. The problem is that Javascript seems to be completely ignorant of culture here. Some cultures use a decimal comma instead of a decimal point, but Javascript bulks at this.
Supporting the decimal comma isn't too much trouble, I can just replace a comma with a decimal point before parsing the users input and I can do the reverse before displaying the result to the user. My question is, is there a way for Javascript to know the users culture settings? I only care about the decimal separator, so for now I have no interest in other complications like thousands separators or currency.
Is there a reliable (client side) way to detect whether a visitor is using the decimal comma rather than the decimal point?
Update
In case anybody else wants it (or if anybody can see a flaw - other than not working in Chrome, as noted - or a better way), I ended up doing this:
var useComma = (0.1).toLocaleString().indexOf(",") > 0;
Now useComma will be true if the user has comma set as their decimal separator
I think that trying to detect the user's locale may not actually help that much. If your Web Application is in English language, a user might actually use English-style formatting (e.g. 1.3) even though in their own culture it would be formatted differently (1,3 for fr-FR or es-ES)! And who would blame them?
You could try and be smart and use the solution proposed by Alex K, and/or take into account the accept-language header, the locales matching your localizations (if any) and even GeoIP for a best guess. But to reduce confusion you may want to give your user cues whenever you expect them to enter numerals or dates or other locale-sensitive data.... Display a default value or an example next to the fields, formatted using the same locale as you will be using to parse user input.
If you believe it gives you better user experience to be flexible, you could use a fallback technique and try the formats you expect the most.
How about
var decimalChar = (0.1).toLocaleString().charAt(1);
Edit, this appears not to work in chrome Internationalization(Number formatting "num.toLocaleString()") not working for chrome
function browser_i18n() {
var o1 = new Intl.NumberFormat().resolvedOptions();
var o2 = new Intl.DateTimeFormat().resolvedOptions();
var o3 = new Intl.NumberFormat().formatToParts( 123456.789 );
return {
locale: o1.locale,
sign: o1.signDisplay,
group: o1.useGrouping,
timeZone: o2.timeZone,
calendar: o2.calendar,
thousands: o3[ 1 ].value,
decimals: o3[ 3 ].value,
}
}
//

How to format numbers using JavaScript?

I want to format number using javascript as below:
10.00=10,00
1,000.00=1.000,00
Every browser supports Number.prototype.toLocaleString(), a method intended to return a localized string from a number. However, the specification defines it as follows:
Produces a string value that represents the value of the Number formatted according to the conventions of the host environment's current locale. This function is implementation-dependent, and it is permissible, but not encouraged, for it to return the same thing as toString.
Implementation-dependant means that it's up to the vendor how the result will look, and results in interoperability issues.
Internet Explorer (IE 5.5 to IE 9) comes closest to what you want and formats the number in a currency style - thousands separator and fixed at 2 decimal places.
Firefox (2+) formats the number with a thousands separator and decimal places but only if applicable.
Opera, Chrome & Safari output the same as toString() -- no thousands separator, decimal place only if required.
Solution
I came up with the following code (based on an old answer of mine) to try and normalize the results to work like Internet Explorer's method:
(function (old) {
var dec = 0.12 .toLocaleString().charAt(1),
tho = dec === "." ? "," : ".";
if (1000 .toLocaleString() !== "1,000.00") {
Number.prototype.toLocaleString = function () {
var neg = this < 0,
f = this.toFixed(2).slice(+neg);
return (neg ? "-" : "")
+ f.slice(0,-3).replace(/(?=(?!^)(?:\d{3})+(?!\d))/g, tho)
+ dec + f.slice(-2);
}
}
})(Number.prototype.toLocaleString);
This will use the browser's built-in localization if it's available, whilst gracefully degrading to the browser's default locale in other cases.
Working demo: http://jsfiddle.net/R4DKn/49/
I know this solution using NumberFormat but it is necessary to convert the values to string.
https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/NumberFormat
// Remove commas
number = "10,000.00".replace(/,/g, '');
// Create a NumberFormat type object
var formatter = new Intl.NumberFormat('de-DE', {
minimumFractionDigits: 2
});
// Apply format
console.log(formatter.format(number));
output:10.000,00
Javascript doesn't provide this functionality itself, but there are a number of third-party functions around which can do what you want.
Note, whichever method you use, you should be careful to only use the resulting string for display purposes -- it won't be a valid number value in Javascript after you've converted the decimal point to a comma.
The quickest solution I can offer is to use the number_format() function written by the phpJS people. They've implemented Javascript versions of a load of commonly-used PHP functions, including number_format(), and this function will do exactly what you want.
See the link here: http://phpjs.org/functions/number_format
I wouldn't bother about taking the whole phpJS library (a lot of it is of questionable value anyway), but just grab the 20-odd line function shown on the page linked above and paste it into your app.
If you want a more flexible solution, there are a number of JS functions around which simulate the printf() function from C. There is already a good question on SO covers this. See here: JavaScript equivalent to printf/string.format
Hope that helps.

Categories