Currency symbol with another number format - java

I was wondering if there was an elegant way to set the currency format of a number in one way but keep the actual number formatting in another. It is Java. Essentially I am doing this
NumberFormat format = NumberFormat.getCurrencyInstance(locale);
This is largely fine except I am writing a system for UK based users and my users are upset that when showing (for example) euros the number is formatted as europeans would use it. So € 500,000 as a UK person would write it is displaying as € 500.000 (i.e. swap , for .). I was going to swap locale for locale.UK but then I will have the wrong currency symbol!
I have a couple of dirty fixes for this but I wondered if there was an elegant way to keep the currency symbol of the locale with the local locale (locale.UK) number format.

Different currencies can also place the currency symbol before or after the string, or have a different number of decimal places (if any). It is not really clear from your question how you want to handle those cases, but assuming you want to preserve those differences, try this.
Instead of just swapping in the currency symbol into your local number format, you could start with the foreign format and substitute the decimal format symbols with your local version. Those also include the currency, so you have to swap that back (don't worry, it's a copy).
public static NumberFormat localStyleForeignFormat(Locale locale) {
NumberFormat format = NumberFormat.getCurrencyInstance(locale);
if (format instanceof DecimalFormat) {
DecimalFormat df = (DecimalFormat) format;
// use local/default decimal symbols with original currency symbol
DecimalFormatSymbols dfs = new DecimalFormat().getDecimalFormatSymbols();
dfs.setCurrency(df.getCurrency());
df.setDecimalFormatSymbols(dfs);
}
return format;
}
This way, you also retain the correct positioning of the currency symbol and the number of decimal places. Some examples, for default-Locale Locale.UK
en_GB £500,000.00 £500,000.00
fr_FR 500 000,00 € 500,000.00 €
it_IT € 500.000,00 € 500,000.00
ja_JP ¥500,000 JPY500,000
hi_IN रू ५००,०००.०० INR 500,000.00
If you also want to preserve the foreign currency symbol, instead of the local equivalent, use
localDfs.setCurrencySymbol(df.getCurrency().getSymbol(locale));

You can specify the currency symbol on the NumberFormat with the setCurrency method.
Then simply use the Locale.UK to have the proper grouping separator displayed.
format.setCurrency(Currency.getInstance("EUR"));
Note that for a better handling of the grouping/decimal separator you might want to use a DecimalFormat instead.
DecimalFormatSymbols custom=new DecimalFormatSymbols();
custom.setDecimalSeparator('.');
custom.setGroupingSeparator(',');
DecimalFormat format = DecimalFormat.getInstance();
format.setDecimalFormatSymbols(custom);
format.setCurrency(Currency.getInstance("EUR"));
Then specify the correct pattern, example "€ ###,###.00".

Related

Java - NumberValue to String without Currency sign

I am trying to format a NumberValue as a String in the current locale format.
For example, for Locale.Germany these would be the results I am trying to get:
1 -> 1,00
1.1 -> 1,10
0.1 -> 0,10
What I have tried:
String test1 = NumberFormat.getInstance().format(1.1);
// -> 1,1
String test2 = NumberFormat.getCurrencyInstance().format(1.1);
// -> 1,10 €
How could I get the same format as the second example, without the currency symbol? Or alternativly, how could I make sure the result from the first example always has the amount of decimals needed for the current locale?
Edit: Since there are some currencies that have 0,2 or 3 decimals, I don't think setting the decimals to a fixed amount will have the correct results.
Also, some currencies have their symbol in the front, and some in the back, so cutting off the last characters will probably not work either.
http://apps.cybersource.com/library/documentation/sbc/quickref/currencies.pdf
java.util.Currency provides the necessary information. A reasonable approach to print currency values without the currency sign in pure Java code is to get a general-purpose NumberFormat instance and configure it to use the number of digits defined by the appropriate Currency object:
NumberFormat numberFormat = NumberFormat.getInstance(myLocale);
Currency currency = Currency.getInstance(myLocale);
numberFormat.setMinimumFractionDigits(currency.getDefaultFractionDigits());
If you need a specific currency as opposed to the default currency of the locale you use, use the String override of Currency.getInstance() instead and provide the appropriate currency code.

Using Default Locale Separator with NumberFormat, and then rounding number

I have this Java code:
NumberFormat nf = NumberFormat.getNumberInstance(Locale.getDefault());
DecimalFormat df = (DecimalFormat)nf;
newCurr = df.format(dCurr);
Basically, I pass in a number, say 12.344.
I want it rounded two places AND to use the Locale's default separator (either "." or ","). So, for example in some countries in Europe, I want this to be 12,34
So far with code above, I am halfway there. I get 12,344. I can't find where to place the DecimalFormat of ("#.##") so it can be rounded.
In other words, I can I incorporate DecimalFormat df=new DecimalFormat("#.##"); in the above? or do I have to find another way?
Edit: I am thinking I have to do the old way of (100.00 * var)/ 100.00 and pass that in?
The method setMaximumFractionDigit will do the work. See the rest of the available methods: http://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html#setMaximumFractionDigits%28int%29

Currency Symbol Internationalization Java

I'm trying to get the number format according to current locale but I have a problem with the currency symbol.
This is my method:
import java.util.Locale;
import java.text.NumberFormat;
public void i18nCurrency(Locale currentLocale) {
Double price = 9876543.21;
NumberFormat currencyFormatter =
NumberFormat.getCurrencyInstance(currentLocale);
System.out.println(currencyFormatter.format(price));
}
It prints: ¤ 9 876 543,21 for uk and ¤9.876.543,21 for german. The number format is correct, but I need to get the currency symbol as well. Why I can't get the symbol?
The symbol you're getting is a universal currency placeholder. It is displayed when currency is unknown.
You probably wonder why it is unknown. Well, from your description you simply called the method passing something like Locale.GERMAN. If you did, there is no way of knowing what currency to use, because:
Euro is a currency of Germany and Austria
Swiss Frank (SFr.) is a currency of Switzerland
Each of these countries has German as at least one of their official languages. In order to resolve the problem, you always need to pass a country, i.e. call the method with Locale.GERMANY as a parameter.
Now, the harder part. It is all fairly easy when you are working with desktop application. All you have to do is to detect current OS locale like this:
Locale currentLocale = Locale.getDefault(LocaleCategory.FORMAT);
However, this method won't work with web applications. I suspect this is the case. Well, the Locale that web browsers give you might be not suitable for formatting currencies, as they may lack information about the country.
The recommended way to solve this issue is to create user profile and ask users to select the Locale (separately for UI translations and formatting purposes).
I still have to point out one important thing, because I don't want you to run into problems. When you have some monetary value in your application (usually it should be an instance of BigDecimal class, as double is not suitable for this purpose), it represents some value in a specific currency. Be it Euro, British Pound, or a Dollar, but the value is specific. It doesn't really make sense to format this value for specific country currency, as you should first change the amount (I believe you understand why).
What you probably need instead, is overriding the currency symbol or currency code to match your currency. The format and the symbol placement should obviously stay intact.
Please consider this example:
Currency dollar = Currency.getInstance("USD");
NumberFormat fmt = NumberFormat.getCurrencyInstance(Locale.GERMANY); //this gets € as currency symbol
BigDecimal monetaryAmount = BigDecimal.valueOf(12.34d);
String originalEuros = fmt.format(monetaryAmount);
System.out.println(originalEuros);
fmt.setCurrency(dollar); // change the currency symbol to $
String modifiedDollars = fmt.format(monetaryAmount);
System.out.println(modifiedDollars);
This prints:
12,34 €
12,34 USD
Wait, why? The answer to your question lies in this subtle code snippet:
System.out.println(currency.getSymbol(Locale.GERMANY));
System.out.println(currency.getSymbol(Locale.US));
The result:
USD
$
What gets printed depends on a Locale. It is probably better this way, I cannot tell...
I believe, unless you are creating Internet currency exchange application, you should stick to my example.

NumberFormatException on European Versions of Android?

I have an app which runs the following two lines of code upon starting:
DecimalFormat decim = new DecimalFormat("#.00");
return Double.parseDouble(decim.format(totalNumberOfCredits));
When I start the app on my American phone, the value of decim.format(totalNumberOfCredits) is .00.
However, in my Google Play Developer Console, I have a dozen crashes, all of which look like this:
Caused by: java.lang.NumberFormatException: Invalid double: ",00"
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseDouble(StringToReal.java:269)
at java.lang.Double.parseDouble(Double.java:295)
Is it really possible that DecimalFormat is producing a comma version of the decimal on European phones?
Is it really possible that DecimalFormat is producing a comma version of the decimal on European phones?
Yes, absolutely. That's what it's meant to do, after all:
Creates a DecimalFormat using the given pattern and the symbols for the default locale. This is a convenient way to obtain a DecimalFormat when internationalization is not the main concern.
To obtain standard formats for a given locale, use the factory methods on NumberFormat such as getNumberInstance. These factories will return the most appropriate sub-class of NumberFormat for a given locale.
Note that this isn't a matter of a "European version of Android" - it's just a matter of using Android in a context where the default locale uses , as the decimal separator.
If you want to use the symbols for a particular locale, but using a specific pattern, you could use:
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(Locale.US);
DecimalFormat format = new DecimalFormat("#.00", symbols);
Having said that, it's not at all clear what you're trying to do in the first place - why would you format and then parse a number? You should almost always avoid string conversions when you don't really need them. Why not just convert it directly? (We don't know what totalNumberOfCredits is, which doesn't help.)
public double getTwoPointDecimal(double value) {
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US);
return Double.parseDouble(new DecimalFormat("##.##", symbols).format(value));
}
try it, its help me in my project
double unit = Float.parseFloat(String);
DecimalFormat decimal = new DecimalFormat("##.###").format(unit);
try this it help me in my project

Formatting numeric values on Android that don't use western digits

On iOS there's a handy function on NSNumber
localizedStringWithStyle:
Which will format a numeric value into a string using digits appropriate to that region (possibly Western, possible Arabic, etc).
I assume in Java on Android a NumberFormat object (or similar) could be configured to do this but I'm not sure how.
So my question. In Android how to you format a number in locale specific digits?
When you instantiate the NumberFormat object, you call it like this:
NumberFormat formatter = NumberFormat.getInstance(Locale.US);
You can pick from the list of static Locales or call NumberFormat.getAvailableLocales() to search for a locale which matches your desired output.
int n;
String.format("%d", n);
That's all. String.format uses the user's locale by default. You can request a particular locale by passing it as the first argument (i.e. before the format string).

Categories

Resources