问题
I have to display a number in currency format using the country code with comma and period separators based on the country.
Example if the number is 4294967295000 then
- USA = USD 4,294,967,295,000.00
- INDIA = INR 42,94,96,72,95,000.00
I got it working for India, but for USA I am getting this string but I need space between currency code and number:
var number = 4294967295000;
console.log(number.toLocaleString('en-IN', {
style: 'currency', currency: 'INR', currencyDisplay: 'code'
})); // INR 42,94,96,72,95,000.00
console.log(number.toLocaleString('en-US', {
style: 'currency', currency: 'USD', currencyDisplay: 'code'
})); // USD4,294,967,295,000.00
How do I achieve spacing between "USD" and number? I did not see anyting in option parameter regarding space. I can write custom code to add space, but I am trying to see if there is better option for doing the same.
回答1:
I did not see anyting in option parameter regarding space.
So I set off down the rabbit hole.
When you pass options in to toLocaleString
, it follows a number of steps. Firstly, it converts your passed in options to a NumberFormat
object. It goes through a series of steps to do so, one of which is:
- If s is "currency", then
a. Let c be converting c to upper case as specified in 6.1.
b. Set numberFormat.[[currency]] to c.
That means that whatever you've passed in as the currency
option, so long as it's a proper currency code, is converted to uppercase and stored in the internal currency
property on the NumberFormat
object.
We then see that there are some other internal properties used on a NumberFormat
- in this case, specifically the positivePattern
internal slot. The spec notes:
The value of these properties must be string values that contain a substring "{number}"; the values within the currency property must also contain a substring "{currency}". The pattern strings must not contain any characters in the General Category “Number, decimal digit" as specified by the Unicode Standard.
IE note that at this point, for a given culture, we've created an object that effectively has a formatting string along the lines of {currency} {number}
. Only in Chrome's (at least) case for USD, it is {currency}{number}
. Note that in IE and Edge, you get the space after USD, so it's decided on a formatting string of {currency} {number}
.
Next up, we get to the actual implementation of formatting the number. Step 7 says:
- If the value of the numberFormat.[[style]] is "currency", then
a. Let currency be the value of numberFormat.[[currency]].
b. If numberFormat.[[currencyDisplay]] is "code", then
i. Let cd be currency.
c. Else, if numberFormat.[[currencyDisplay]] is "symbol", then
i. Let cd be an ILD string representing currency in short form. If the implementation does not have such a representation of currency, then use currency itself.
d. Else, if numberFormat.[[currencyDisplay]] is "name", then
i. Let cd be an ILD string representing currency in long form. If the implementation does not have such a representation of currency, then use currency itself.
e. Replace the substring "{currency}" within result with cd.
emphasis mine, showing the steps taken in this case.
TL;DR - this behaviour appears to browser dependent, and you'll need to parse and fix the resulting string yourself if you consistently want the space, there's no built-in way to do so.
回答2:
If it's a reliable pattern that what you want to fix is a three-letter code followed by a digit, and you want to fix that by inserting a space, you could use this regex like this:
currencyStr = currencyStr.replace(/^([A-Z]{3})(\d)/, (match, $1, $2) => $1 + ' ' + $2);
来源:https://stackoverflow.com/questions/49325561/how-to-get-space-between-currency-code-and-amount-using-localestring-in-javascri