I'm attempting to write a currency formatting function using Intl.NumberFormat.
It works correctly when I pass it things like USD, or EUR as the currency, but seems to break when I pass it more obscure currency codes like PLN or COL, and instead of displaying their symbols as requested it displays the Codes. It is clearly recognizing the code because when I ask it to display the name instead it works correctly:
Intl.NumberFormat("en-US",{
style:'currency',
minimumIntegerDigits:1,
currency: 'PLN',
currencyDisplay: 'symbol'
}).format(43);
Displays "PLN43" while
Intl.NumberFormat("en-US",{
style:'currency',
minimumIntegerDigits:1,
currency: 'PLN',
currencyDisplay: 'name'
}).format(43);
Displays "43.00 Polish zlotys"
The Intl.NumberFormat should have the symbols you need, you just have to make sure you specify the correct language code.
You can find a mapping of ISO language codes here:
https://www.w3schools.com/tags/ref_language_codes.asp
In this case you will need to use the Polish value "pl" instead of "en-US"
Intl.NumberFormat("pl",{
style:'currency',
minimumIntegerDigits:1,
currency: 'PLN',
currencyDisplay: 'symbol'
}).format(43);
According to the spec:
However, the set of combinations of currency code and language tag for which localized currency symbols are available is implementation dependent. Where a localized currency symbol is not available, the ISO 4217 currency code is used for formatting.
Related
Well one can format a value like this:
const formatter new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });
console.log(formatter.format(200));
This automatically selects the "correct" currency symbol. Now what I like is to actually get the symbol (given the locale). I could try formatToParts isn't really doing that since the "parts" are sometimes in a different order: in German the symbol is at the end while in English the symbol is before the amount.
I would like the symbol to be in front of other fields (ie input)
The main important thing to me is not even that the correct symbol is used (it should) - but most important it should always be the same as the one used for displaying.
I'm wanting to convert a specific range of numbers to currency. I'm not sure if such formatting exists in google apps script. I notice that when defining one cell value with a "$", it automatically declares any other numbers in that range with a "$". So I assume that there is some kind of currency type.
If so, is there some type of fancy method to convert a number to this currency format or am I to simply convert each number to a string and add a "$" in front of each one.
Any help would be appreciated, thank you.
You can use a built-in Javascript functionality like this:
var numberToCurrency = new Intl.NumberFormat('en-US', {style: 'currency', currency: 'USD'});
numberToCurrency.format(3600);
Google Apps Script uses JavaScript, as the later doesn't have a currency data type, Google Apps Script either. The V8 engine (default for new project) supports Internationalization API, through the Intl object, but the old engine (Rhino) doesn't.
If your project is using the default settings, you might use Intl.NumberFormat (examples taken from MDN)
const number = 123456.789;
console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"
// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "¥123,457"
It's worthy to note that Google Sheets stores "currency" values as numbers. The "$" is added by the automatic number formatting feature. If you want that your script adds this formatting use setNumberFormat.
Related
How to format numbers as currency strings
Set cell format with google apps script
Intl.NumberFormat String Currency before number
I find toLocaleString function very odd.
the following line will return 0.003:
alert(0.0031.toLocaleString(2))
this line will return 0:
alert(0.00031.toLocaleString(2))
why?
This is not a valid parameters to the method toLocaleString.
You can use minimumFractionDigits param like this:
var res = 0.00031.toLocaleString(undefined, {minimumFractionDigits: 4});
console.log(res);
The toLocaleString() method returns a string with a language sensitive representation of this number.
numObj.toLocaleString([locales [, options]]) has two parameters.
Reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString
var num = 0.00031;
console.log(num.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}));
console.log(num.toLocaleString(undefined, { maximumFractionDigits: 4}));
toLocaleString truncates and rounds the decimal number to 3 digits after the decimal.
0.0005.toLocaleString()
for example will return 0.001.
The 2 in that you pass in as a method param doesn't do anything.
2 is not a valid argument for toLocaleString method of a Number. You may only pass a locale, which is a string, and and an object of options.
Options object can be used, among other things, to specify number of fraction digits:
number.toLocaleString(undefined, { maximumFractionDigits: 4 })
And the default value for it happens to be 3:
maximumFractionDigits
The maximum number of fraction digits to use.
Possible values are from 0 to 20; the default for plain number
formatting is the larger of minimumFractionDigits and 3; the default
for currency formatting is the larger of minimumFractionDigits and the
number of minor unit digits provided by the ISO 4217 currency code
list (2 if the list doesn't provide that information); the default for
percent formatting is the larger of minimumFractionDigits and 0.
The number 2 in the argument is not making any difference. toLocaleString returns a string with a language sensitive representation of the number.
In the second case of your problem it is basically 0.000 which is equal to 0
console.log("Passing argument " + 0.0031.toLocaleString(2))
console.log("Without argument " + 0.0031.toLocaleString())
console.log("Zeros " + 0.000)
number.toLocaleString() returns language sensitive representation of the number. Here in your case you are first not passing any locale information, and you are not telling this function that what is your max fraction limit.
See this example
0.0003.toLocaleString(undefined, {minimumFractionDigits: 2})
"0.00"
0.0003.toLocaleString(undefined, {minimumFractionDigits: 3})
"0.000"
0.0003.toLocaleString(undefined, {minimumFractionDigits: 4})
"0.0003
As per spec, first two arguments to toLocaleString is locale and options
When the toLocaleString method is called with optional arguments
locales and options, the following steps are taken:
When this API receive value 2 or 3, it first try to resolve locales and if not found the check within the supported locales.
The resolved locale is used as an effective locale to format the number as per the locale as per Common Locale Data Repository.
NOTE It is recommended that implementations use the locale data
provided by the Common Locale Data Repository (available at
http://cldr.unicode.org/).
As per documentation
The locales argument must be either a string holding a BCP 47 language
tag, or an array of such language tags. If the locales argument is not
provided or is undefined, the runtime's default locale is used.
A BCP 47 language tag defines a language and minimally contains a
primary language code. In its most common form it can contain, in
order: a language code, a script code, and a country or region code,
all separated by hyphens. While the tag is not case sensitive, it is
recommended to use title case for script code, upper case for country
and region codes and lower case for everything else.
Finally, lookup is performed to find the best fit from the supported locales as per BCP47 logic as per locales registered in IANA language subtag registry as per various attributes of a language mentioned.
2 doesn't matches any of the supported locales so, default maximum fraction digits as per your system environment is used from available value (appears to be 3 in your case.)
Hence you get
0.00031.toLocaleString(2) //"0"
0.0031.toLocaleString(2) //"0.003"
I'm using a quite simple script to format numbers:
gst = '123.45';
currency = 'EUR';
money = gst.toLocaleString('en-US', {
style: 'currency',
currency: currency,
currencyDisplay: 'code'
});
this will out put this:
EUR123.45
which is, what I want. But I find it kind of ugly that there is no space between the currency and the value. Is there a way to manage this without using a .replace() after the operation?
Thanks in advance
I'm positive there is no specification if toLocaleString that will do this without the replace. You either need to prepend or adjust after the toLocaleString operation.
I am setting up a multilingual site that deals with currencies. I want to be able to display correct currency formats based on the selected language. The server side PHP stuff is a doddle. Using a combination of PHPs NumberFormatter and strftime I have been able to format currencies and dates correctly.
There is however a requirement to have the same degree of formatting done client side with javascript.
I have come across Globalization (former jQuery plugin) and it looks quite promising.
If I want to display a dollar value in American English I can do something like this:
jQuery.preferCulture("en-US");
// Formatting price
var price = jQuery.format(3899.888, "c");
//Assigning stock price to the control
jQuery("#price").html(price);
and this will output:
$3,899.89
While doing:
jQuery.preferCulture("fr-FR");
// Formatting price
var price = jQuery.format(3899.888, "c");
//Assigning stock price to the control
jQuery("#price").html(price);
outputs:
3 899,89 €
which looks perfect. however, I have a need to output multiple currencies. So, if I have 'fr-FR' selected as my preferred culture, how can I output, say, a dollar value like so:
3 899,89 $
so that the format is French, but the value is American Dollar. I have looked but not found anyway to pass a currency symbol as an argument.
The only documented way to modify the currency symbol in Globalize is to change the numberFormat.currency.symbol property of a given culture—in this case, the fr-FR culture. This will kind of do what you want, but it’s not a very elegant solution, and you would need to manually build a table of correct symbols for each locale and write another method to swap them out. (n.b. It is possible to pass a third argument to Globalize.format with a different locale identifier, but this just formats the number using that locale’s cultural settings.) Looking at the culture definition syntax, there is simply no provision for displaying different currencies using a given locale.
If you were to look elsewhere, the dojo/currency module in the Dojo Toolkit does do exactly what you need, using data from the Unicode Common Locale Data Repository to determine how to represent various currencies in different locales. So you can set your locale to fr, write currency.format(3899.888, { currency: "USD" }), and it will output the currency in USD in the correct format for the French locale.
I had the same problem, in the end I just replaced the default currency symbol on the output with the symbol I wanted to display. It's a bit primitive but it keeps the formatting correct for the locale with the currency symbol you want.
function formatCurrency(value, format, symbol){
var formattedValue = Globalize.format(value, format);
if (typeof symbol === "string") {
formattedValue = formattedValue.replace(Globalize.culture().numberFormat.currency.symbol, symbol);
}
return formattedValue;
}
document.getElementById("price1").innerHTML = formatCurrency(123.34,"c"); //<-- $123.34
document.getElementById("price2").innerHTML = formatCurrency(123.34,"c","£"); //<-- £123.34
Here is the fiddle