go-playground / locales

:earth_americas: a set of locales generated from the CLDR Project which can be used independently or within an i18n package; these were built for use with, but not exclusive to https://github.com/go-playground/universal-translator
MIT License
268 stars 55 forks source link

Missing Currency Symbols #11

Open kumarharsh opened 7 years ago

kumarharsh commented 7 years ago

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?

deankarn commented 7 years ago

@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.

kumarharsh commented 7 years ago

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.

kumarharsh commented 7 years ago

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
}
deankarn commented 7 years ago

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.

kumarharsh commented 7 years ago

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.

kumarharsh commented 7 years ago

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.

deankarn commented 7 years ago

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

kumarharsh commented 7 years ago

Ok but still trying to understand what you wouldn't use the locale that has the currency symbol?

So, my scenario is this:

I hope I was able to clarify my usecase, but let me know if you need more info.

deankarn commented 7 years ago

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!

deankarn commented 7 years ago

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.

deankarn commented 7 years ago

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.

kumarharsh commented 7 years ago

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.

bojanz commented 3 years ago

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.

jmooring commented 2 years ago

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.