locales
locales copied to clipboard
Missing Currency Symbols
Hello,
While using the en_US
Translator, I noticed that all the currency symbols are just the short-names USD
, INR
, EUR
, etc, but there are no symbols ($
, ₹
, €
). Is there a way to specify my own currency symbols while initializing a Translator?
@kumarharsh could you can provide some more details about how your using the package?
it's built this way to denote a differing currency because some currency symbols are the same even though they're currency codes differ, there would be no way to differentiate them.
Yes there is a way to accomplish what your looking for, but will require more work on your part, Translator is an Interface so you can copy-paste-modify you're own with a way to get the currency symbols you want.
Translator is an Interface so you can copy-paste-modify you're own with a way to get the currency symbols you want.
@joeybloggs yes, I understand that. I also saw one of the examples in the universal-translator repository to this effect. I was under the impression that it'd be more like an 'import-and-use' kind of library. I agree that some currency symbols are dubious, but on first thought, I don't agree with the decision of leaving them off altogether (except for some inconsistencies, such as the Yen symbol being used, but not Euro or Rupee). The reason why I feel this is that it's almost always going to be more work rather than less for the end-user to use the library IMO.
This is how I'm using it:
package core
import (
"fmt"
"github.com/go-playground/locales"
"github.com/go-playground/locales/currency"
)
// FormatValue formats a raw float64 value into a string with
// proper format and in the correct i18n locale
func FormatValue(value float64, l locales.Translator, displayFormat map[string]interface{}) string {
var fmtValue string
if displayFormat == nil {
fmtValue = fmt.Sprintf("%.2f", value)
}
// displayFormat is an object with 'type' denoting the format of the value, and 'value' denoting an optional sub-type of the format.
switch displayFormat["type"] {
case "number":
fmtValue = l.FmtNumber(value, 2)
case "percentage":
fmtValue = l.FmtPercent(value/100.0, 0) // NOTE: percent format multiplies value by 100 (eg 0.61 is 61%)
case "currency":
var cy currency.Type
switch displayFormat["value"] {
case "USD":
cy = currency.USD
case "CAD":
cy = currency.CAD
case "INR":
cy = currency.INR
}
fmtValue = l.FmtCurrency(value, 2, cy) // right now, outputs things like USD2,000.00
default:
fmtValue = fmt.Sprintf("%.2f", value)
}
return fmtValue
}
Ok I understand the code, I mean the context of your application
eg. Why are you using en_US translator to try and display other locales currency symbols? Why not use the appropriate locale that contains the symbol?
I'm just trying to understand your use case to see if there's anything I can do for you.
Please keep in mind that all of this is generated from the CLDR files and they as far as I know don't even have the short names, that's something I did and perhaps I can take it one step further for your case if it makes sense to.
Please keep in mind that all of this is generated from the CLDR files and they as far as I know don't even have the short names, that's something I did
I see. Sorry, I didn't know that. If you do intend to implement it, for reference, From the Javascript docs for the global Intl
object (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat), there is a currencyDisplay
option which can be used to change the USD200
to $200.00
.
I found the currency symbols defined in Firefox's source code: https://dxr.mozilla.org/mozilla-central/source/intl/icu/source/data/curr/en.txt. They also feature symbol differentiation between similarly named but different currencies - such as USD, CAD, AUD have symbols: '$', 'CA$', 'A$'. These lists might help with building the symbols.
If you need help, I can submit a PR, but I'm not fully aware of the process by which you build each locale's list.
Ok but still trying to understand what you wouldn't use the locale that has the currency symbol?
I prefer to stick to the CLDR data so that I can keep it maintainable.
the generation logic instructions are here https://github.com/go-playground/locales/blob/master/cmd/README.md
Ok but still trying to understand what you wouldn't use the locale that has the currency symbol?
So, my scenario is this:
- I have a multi-language app. User has selected their locale as "en-US".
- All the numbers are formatted in this locale (en-US) using
react-intl
. So, for example, a value of2000
will be formatted as$2,000.00
. - I'd like the same formatting to also reflect while sending them emails. For this, I'd programmatically pick up the locale they've set in their account. So, my email program would select
en-US
as the locale. - But using this library, all I can get is
USD2,000
. I'd like the library to output the$
symbol, but there is no way to know which locale has the$
symbol -en
has it, buten_US
oren_IN
don't. Similarly, none of these locales have the₹
symbol, and so on.
I hope I was able to clarify my usecase, but let me know if you need more info.
Yes definitely helps thanks! I understand the issue now and for locale en_US and the FmtCurrency you should get $2000.00
I'll write up a test to confirm, perhaps I have inadvertently introduced a bug during my last changes.
Thanks for all the info!
Hey @kumarharsh
There is an issue with some of the en
sub languages en_US
, en_GB
... en_CA
seems to be fine.
I'll take a look as soon as I am able, really busy right now so can't guarantee when I'll be able to fix it. but if you wanted to help that would be great!
Thanks again for all the info to find this bug.
Hey @kumarharsh
So I looked into this some more and you should use locale en
instead of en_US
Long Story:
Whenever I can find some time I'll be converting my code generation from using the XML files to the new CLDR JSON repositories to avoid some small issues, and make my generation code a little bit cleaner, and it appears that there is no en_US
in the list see here. I'm pretty sure it's intended to that en
be used in place of en_US
.
Instead of making a fix that may break in the future for you, it may be better to just use en
that way it's future proof.
This list is perfect! Exactly what I wanted as a data source. Are you using this list for generating the data in your repo? I can contribute to this repo to use the CLDR JSON data source.
Also, yes en_US
is not there in the list, but it's there in your's. You can replace en_US
with en_IN
in the examples above, which is present in both lists.
Might make sense to take a look at my https://github.com/bojanz/currency, or more precisely gen.go, which has a lot of parsing logic to fit CLDR symbols and number formats (cldr-numbers-full) into a small footprint.
According to this chart, when locale = en_GB
(the "all others" annotation), the currency symbol should be £
. Instead, we're getting GBP.
If we specify a locale explicitly listed it works as expected. But if a locale is not explicitly listed (the "all others" category), we get the wrong value.