The below code (which is in JODA) prints: €12,23
String formatAmount = new MoneyFormatterBuilder().
appendCurrencySymbolLocalized().
appendAmountLocalized().
toFormatter().
withLocale(new Locale("es", "ES")).
print(Money.of(CurrencyUnit.EUR, 12.23));
System.out.print(formatAmount);
The below code prints: 12,23 €
String formatAmount = NumberFormat.
getCurrencyInstance(new Locale("es", "ES")).
format(amount);
System.out.print(formatAmount);
Can someone tell me which one is correct and why both the libraries print differently?
Related
Language: Java
Problem: I need to set the currency code manually in java. Let's say "USD" and locale can be either "fr-CA" or "en_US" based on the user logged in . I am unable to find the solution where we can do the number format by setting the manual currency and displaying the symbol with number in the output. Please note currency code will not be the same as the locale and vice versa.
For example, if my currency is USD then based on the different locale, the number should be formatted and the output should be as below.
$1,300,000.00 - english
1.300.000,00 $ - Deutch
1 300 000,00 US$ - Potuguese
1 300 000,00 $ US - France canada
Tried below but it does not give the expected output:
Currency currencyInstance1 = Currency.getInstance("USD"); // This can change based on the user input on the UI.
NumberFormat numberFormat4 = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH);
numberFormat4.setCurrency(currencyInstance1);
System.out.println(numberFormat4.format(amount4));
Actual output : 123 456,79 USD
**Expected output:**
For french canada: 1 300 000,00 $ US
For Portuguese : 1 300 000,00 US$
For Deutch : 1.300.000,00 $
Any help is appreciated.
Cross currency for cross locale is not supported in Java.
Country codes are an important locale component because of java. text.Format objects for dates, time, numbers, and currency are particularly sensitive to this element. Country codes add precision to the language component of a locale. For example, French is used in both France and Canada. However, precise usage and idiomatic expressions vary in the two countries.
These differences can be captured with different locale designators in which only the country code is different. For example, the code fr_CA (French-speaking Canada) is different from fr_FR (French-speaking France).
So if we need to fetch the symbol then we would need to create a map with the locale and currency. Pass the currency to fetch the symbol and then use replace to add it.
public static Map<Currency, Locale> currencyLocaleMap;
static {
currencyLocaleMap = new HashMap<>();
List<Locale> availableLocales =
Arrays.asList(Locale.getAvailableLocales());
List<Locale> supportedLocales = new ArrayList<>();
supportedLocales.add(Locale.forLanguageTag("en-US"));
List<Locale> filteredLocales = supportedLocales.stream().filter
(eachLocale -> availableLocales.contains(eachLocale)).collect(Collectors.toList());
System.out.println("UtilTemp : Locales supported : " + filteredLocales);
for (Locale locale : filteredLocales) {
try {
if(!locale.getCountry().isEmpty()){
Currency currency = Currency.getInstance(locale);
currencyLocaleMap.put(currency, locale);
}
}
catch (Exception e) {
}
}
}
public static String getCurrencySymbol(String currencyCode) {
Currency currency = Currency.getInstance(currencyCode);
System.out.println("UtilTemp :" + currencyLocaleMap);
return currency.getSymbol(currencyLocaleMap.get("USD"));
}
I am new in Android development and i am stuck at a place. I want to format my currency, I am setting to show without decimal places and with commas.
Example: right now it's showing like 23000.00. But I want the currency like 23,000; how can I do that?
I tried the formatter classes but that doesn't help me.
This is how it's set now.
public class CurrencyFormatter {
public static String setsymbol(BigDecimal data, String currency_symbol)
{
NumberFormat format = NumberFormat.getCurrencyInstance(Locale.ENGLISH);
format.setCurrency(Currency.getInstance(currency_symbol));
String result=data+" "+" دينار";
return result;
}
}
I expect output to be (arabic text)23,000 instead of (arabic test)23000.00
Basically, you need a currency formatter object.
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(currentLocale);
After that you can format an amount of money:
Double currencyAmount = new Double(23000.00);
String formattedOutput = currencyFormatter.format(currencyAmount);
There are more options and explanations available here on Oracle's reference document: https://docs.oracle.com/javase/tutorial/i18n/format/numberFormat.html
check this
NumberFormat format = NumberFormat.getCurrencyInstance(Locale.getDefault());
format.setCurrency(Currency.getInstance("USA"));
String result = format.format(1234567.89);
This is the format set of usa you can change with your country code
reference check description here
Try this, it will show in this format 23,000 without decimal points, It will show thousand separator in the number.
String result = null;
try {
// The comma in the format specifier does the trick
result = String.format("%,d", Long.parseLong(data)); // use this result variable where you want to use.
result = result + " " + " دينار"; // to append arabic text, do as you were doing before.
} catch (NumberFormatException e) {
}
I am writing website in 3 languages i.e. English, Arabic and Persian. I am trying to show the user this website in relative language. For example if the browser language is Arabic then website will be displayed in Arabic and if its is Persian then Persian website will be display
Here what I did so far:
private Locale locale(){
Locale locale=null;
if(country == null){
locale = request.getLocale();
if(locale.equals("ar")){
locale = new Locale("ar", "AE");
}
else if(locale.equals("fa")){
locale = new Locale("fa", "IR");
}
else if(locale.equals("en")){
language = "en";
locale = new Locale("en", "US");
}
}else{
locale = new Locale(language, country);
}
System.out.println("return---locale=>"+locale);
return locale;
}
This method printing locale=>ar
ResourceBundle rb = ResourceBundle.getBundle("LabelBundles.Labels",locale());
if(country == null){} block is not working whereas else{
locale = new Locale(language, country);
}
is working fine.
2) locale = request.getLocale(); output is "ar" whilst locale = new Locale(); requires two values that is language_COUNTRY so why its giving output as "ar" only without country?
Please advise and thanks in anticipation
request.getLocale() returns a Locale, not a String. So
locale.equals("ar")
will always be false: only a String can be equal to a String. And only a Locale can be equal to a Locale.
You can however do
if (locale.getLanguage().equals("ar"))
Regarding your second question, it's of course answered by the javadoc. If you read it, you'll learn that a locale is a language, + an optional country, + an optional variant. And there is a constructor taking only a language as argument.
Read the javadoc. That's how you learn.
I need to format currency correctly based on locale, but our customer disagrees with the default formatting that Java does based on some locales.
What standard is the formatting based on that Java uses for the NumberFormat returned by NumberFormat.getCurrencyInstance(), if any, and is this documented anywhere?
Below is some example code that shows how Java formats currency based on Locale.
public static void main(String[] args)
{
displayCurrency(Locale.ENGLISH);
displayCurrency(Locale.FRENCH);
displayCurrency(Locale.ITALIAN);
}
static public void displayCurrency( Locale currentLocale) {
Double currencyAmount = new Double(9876543.21);
DecimalFormatSymbols symbol = new DecimalFormatSymbols(currentLocale);
symbol.setCurrencySymbol("$");
DecimalFormat currencyFormatter = (DecimalFormat)
NumberFormat.getCurrencyInstance(currentLocale);
currencyFormatter.setDecimalFormatSymbols(symbol);
System.out.println(
currentLocale.getDisplayName() + ": " +
currencyFormatter.format(currencyAmount));
}
Output:
English: $9,876,543.21
Italian: $ 9.876.543,21
French: 9 876 543,21 $
I18n in Java is defined by the UNICODE standard, so you can find the information about how to format currencies at http://www.unicode.org/cldr/charts/latest/supplemental/detailed_territory_currency_information.html
In the source code, the same information is stored in the JDK rt.jar and localedata.jar files, in packages sun.util.resources and sun.text.resources (files are called CurrencyNames_xx_XX.class)
Probably it takes de default curreyncy from the JVM you are using. there is a file currency.data in the lib folder of the jre
I got a bug report from a Swedish user saying that our Swedish currency was using the wrong decimal separator.
NumberFormat enUS = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat enGB = NumberFormat.getCurrencyInstance(Locale.UK);
NumberFormat svSE = NumberFormat.getCurrencyInstance(new Locale("sv", "SE"));
double cost = 1020d;
String fmt = "en_US: %s en_GB %s sv_SE %s";
String text = String.format(fmt, enUS.format(cost), enGB.format(cost), svSE.format(cost));
Log.e("Format", text);
> Format﹕ en_US: $1,020.00 en_GB £1,020.00 sv_SE 1 020:00 kr
They say that the format should be "1 020,00 kr". When I inspect the format object, it looks like it has decimalSeparator of "," in the symbols table, but a "monetarySeparator" of ":".
Does anyone know if : is actually correct, whether this is a bug in Android/java, or any sort of workaround?
It's like your user says: In Swedish thousand separator is white space " " and decimal separator is comma "," and currency symbol "kr" (Krona). So colon ":" is definitely wrong.
You can check it here too: http://www.localeplanet.com/java/sv-SE/
What Java version are you using? It works well on my desktop 1.6.0_13
-- update --
It seems that on Android there's a bug, but you can go around the bug by using the DecimalFormatSymbols like this:
DecimalFormat svSE = new DecimalFormat("#,###.00");
DecimalFormatSymbols symbols = new DecimalFormatSymbols(new Locale("sv", "SE"));
symbols.setDecimalSeparator(',');
symbols.setGroupingSeparator(' ');
svSE.setDecimalFormatSymbols(symbols);
This prints the correct separators in Android as well.