locales icon indicating copy to clipboard operation
locales copied to clipboard

Missing Currency Symbols

Open kumarharsh opened this issue 7 years ago • 14 comments

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 avatar May 08 '17 12:05 kumarharsh

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

deankarn avatar May 09 '17 02:05 deankarn

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 avatar May 10 '17 07:05 kumarharsh

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
}

kumarharsh avatar May 10 '17 08:05 kumarharsh

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.

deankarn avatar May 11 '17 01:05 deankarn

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 avatar May 11 '17 04:05 kumarharsh

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.

kumarharsh avatar May 11 '17 06:05 kumarharsh

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

deankarn avatar May 11 '17 09:05 deankarn

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 of 2000 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, but en_US or en_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.

kumarharsh avatar May 11 '17 10:05 kumarharsh

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 avatar May 11 '17 11:05 deankarn

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 avatar May 12 '17 00:05 deankarn

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.

deankarn avatar May 14 '17 13:05 deankarn

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.

kumarharsh avatar May 15 '17 05:05 kumarharsh

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.

bojanz avatar Nov 08 '20 15:11 bojanz

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.

jmooring avatar Mar 14 '22 15:03 jmooring