I have a method that convert a number into a currency, for "USD" and "GBP" it's working good, but with "EUR" the NumberFormat it's rendering a string with a space between the symbol and the number € 1.207.987,00 rather then dollar and pound "$1,207,987.00", "£1,207,987.00". I tried use replace and replace all to remove this but nothing works for me, follow the code:
public static void main(String[] argsd) {
Number rawNumber = 120798700;
NumberFormat numberFormat = NumberFormat.getCurrencyInstance(Locale.forLanguageTag("nl"));
Currency currency = Currency.getInstance("EUR");
numberFormat.setCurrency(currency);
String numberRemoveSpaces = numberFormat.format((rawNumber.floatValue() / 100)).replaceAll("\\s+", "");
System.out.println(numberRemoveSpaces);
}
If you want to remove it, try this:
String numberRemoveSpaces = numberFormat.format((rawNumber.floatValue() / 100)).replaceAll("\\p{Z}","");
That removes any kind of whitespace or invisible separator.
You can use the following, instead of your current replaceAll():
replaceFirst("\\u00A0", "")
The Unicode value of U+00A0 is a non-breaking space (see here). This is the specific character being used to separate the currency symbol from the amount.
You can also choose to build a custom format as follows:
NumberFormat nf = NumberFormat.getCurrencyInstance();
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setCurrencySymbol("€");
dfs.setGroupingSeparator('.');
dfs.setMonetaryDecimalSeparator(',');
((DecimalFormat) nf).setDecimalFormatSymbols(dfs);
System.out.println(nf.format(rawNumber.floatValue() / 100));
This also gives the same output:
€1.207.987,00
Thanks guys for all the answers but according with http://www.bubblefoundry.com/blog/2013/11/formatting-dutch-currency-amounts/ the default format for Netherlands currency have the space between the symbol and number, so i'll keep with the space.
Related
I'm trying to find a way to display currency with a dot so for instance it should be
1.234,56 kr.
At the moment I'm using
pattern = "#,##0.00 ¤";
new DecimalFormat(pattern);
This doesn't work as the Danish krone is for some reason defined there as kr instead of officially recognized kr.
I've looked for a way to escape these characters using Unicode value that I would add to pattern but that doesn't work. In the official documentation here I don't see a way to do it either.
TLDR: I want to add full stop after currency symbol. So at the moment I have it like this kr , what I want to get is kr. .
The output of currency values depends on the respective country setting. If you want to explicitly have a decimal point as in your case, you have to set a corresponding locale for the Numberformat. E.g. English for a point.
For Example:
public String FormatWithPoint(double yourValue){
NumberFormat nf = NumberFormat.getNumberInstance(Locale.ENGLISH);
nf.setGroupingUsed(false);
return nf.format(yourValue);
}
Edit: If you need more control, you can also do the following:
public String FormatCurreny(double yourValue){
NumberFormat nf = NumberFormat.getCurrencyInstance();
nf.setGroupingUsed(false);
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setCurrencySymbol("kr.");
dfs.setMonetaryDecimalSeparator('.');
((DecimalFormat) nf).setDecimalFormatSymbols(dfs);
return nf.format(yourValue);
}
If you just want the dot after the currency symbol you can set a custom currency symbol. Here I did it using euros (note that instead of "€." you can put my_symbol.getCurrencySymbol()+"." if you want it for all currency and not just one):
DecimalFormatSymbols my_symbol = new DecimalFormatSymbols();
my_symbol.setCurrencySymbol("€.");
String pattern = "###,###.###¤";
DecimalFormat decimalFormat1 = new DecimalFormat(pattern, my_symbol);
String format = decimalFormat1.format(987654321.321);
System.out.println(format);
This gives
987.654.321,321€.
I am not sure if the same question is asked by any other. I have not seen this question in stackoverflow so far, hence posting the same.
I have a requirement where I need to format the numbers based on the currency.
Let me explain the above table to give you more context of my question. For UnitedStates, numbers are formatted as USD976,543.21, here the currency symbol is USD which is placed in the front before numbers. This is little different for fr-FR locale, here € symbol is placed after the digits.
All my formatting is happening in the front end and not the backend. I am giving a format in the form of # to the FE, then our home grown code formats the digits in that format. Example, for United states, I am supplying USD###,###,###.####. Here, I need to let the front end know the below information so that front end formats the same in a prompt manner.
My question is:
Is there any way to get the below information in the backend:
Where to place the currency, start of the number or towards ending?
Is there any space between number and symbol? Look at USD976,543.21 and 976 543,21 € . There is space between currency symbol and number for EURO but not for USD.
I am using java.util.Currency.
I found this question while searching for a way to determine whether the currency symbol should be placed at the start or end of a currency for a specific locale. For others who might be looking for something similar, I ended up creating the following class to test this:
public class Test {
private static Locale[] locales = Locale.getAvailableLocales();
static double decimal = 789456123.098;
public static void main(String[] args) {
for(Locale locale : locales){
DecimalFormat decimalFormatter = (DecimalFormat)NumberFormat.getInstance(locale);
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale);
DecimalFormatSymbols symbols = decimalFormatter.getDecimalFormatSymbols();
String currencySymbol = symbols.getCurrencySymbol();
String formattedCurrency = currencyFormatter.format(decimal);
System.out.print(formattedCurrency + ";" + locale.getDisplayCountry() + ";" + locale.getDisplayLanguage() );
System.out.println(";" + currencySymbol + ";" + currencySymbolAtStart(currencySymbol, formattedCurrency, true));
}
}
private static boolean currencySymbolAtStart(String currencySymbol, String formattedCurrency, boolean defaultAtStart){
if(formattedCurrency.startsWith(currencySymbol)){
return true;
}else if(formattedCurrency.endsWith(currencySymbol)){
return false;
}else{
return defaultAtStart;
}
}
}
Pasting the results into a spreadsheet looks something like this:
There is one caveat here to be aware of. For languages that are read right to left, the currency symbol might appear on the right in the formatted text, yet technically, since you are reading from right to left, the currency still "starts with" the currency symbol, hence the result will return "true". See Egypt-Arabic in the screen snip above...
Great explanation and code is here: https://drivy.engineering/multi-currency-java/
I would say use the standard, instead of pleasing your designers.
You can use Globalizejs for your requirement
A JavaScript library for internationalization and localization that leverages the official Unicode CLDR JSON data
It's pretty easy to start with and you need not worry about placing the currency code in front or at the end, The library will take care according to locale and currencyCode.
Example:
var formatter;
Globalize.locale( "en" );
formatter = Globalize.currencyFormatter( "USD" );
formatter( 9.99 );
// > "$9.99"
in different locale:
var deFormatter = Globalize( "de" ).currencyFormatter( "EUR" );
deFormatter( 9.99 );
// > "9,99 €"
The NumberFormat.getCurrencyInstance() can be used to format a number according to the currency of a particular locale in the backend. And the formatted currency can be passed to FE for rendering. For example:
double num = 976_543.21;
NumberFormat defaultFormat = NumberFormat.getCurrencyInstance(new Locale("fr","FR"));
System.out.println(defaultFormat.format(num)); //output 976 543,21 €
Locale us = new Locale("en", "US");
NumberFormat usFormat = NumberFormat.getCurrencyInstance(us);
System.out.println(usFormat.format(num)); //output $976,543.21
So I'm getting a crash java.lang.NumberFormatException: Invalid float: "٠" because for some reason on Egyptian devices the decimal delimiter is ٠ instead of .
How do I solve this? It can handle users who have , (comma) as the decimal symbol, but this weird dot causes a crash. Here's the code that's the problem:
DecimalFormat oneDigit = new DecimalFormat("#.#");
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setDecimalSeparator('.');
oneDigit.setDecimalFormatSymbols(dfs);
sevenDaysAverage = Float.valueOf(oneDigit.format(sevenDaysAverage)); // exception here
My goal is to have a number formatted with a single decimal delimited by a dot, because the app is in English and that's how the number should be displayed.
String f = "20.0"; // suppose . is weird symbol
String f1 = f.replace(".","."); // replace weird dot with decimal point
Then convert f1 to String.
sevenDaysAverage = Float.valueOf(f1);
That's an Arabic Zero not a decimal point,
You ought to use NumberFormat class.It allows you to parse Strings into a locale aware number. This would prevent you from facing situations where the decimal separator character is , For example in case of German, it would be:
NumberFormat nf_ge = NumberFormat.getInstance(Locale.GERMAN);
String number_ge = nf_ge.format(1000000);
If you want the grouping separator to be a point, you can use an european locale:
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
DecimalFormat df = (DecimalFormat)nf;
Alternatively you can use the DecimalFormatSymbols class to change the symbols that appear in the formatted numbers produced by the format method. These symbols include the decimal separator, the grouping separator, the minus sign, and the percent sign, among others:
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(currentLocale);
otherSymbols.setDecimalSeparator(',');
otherSymbols.setGroupingSeparator('.');
DecimalFormat df = new DecimalFormat(formatString, otherSymbols);
is there a class in Java that lets you format a number like "102203345.32" to this "102.203.345,32" and return a string type?
I would like to obtain a String where the thousands are separated by the '.' and the decimals are separated by a comma ','.
Could someone help me please? I found a class DecimalFormat and I tried to customize it:
public class CustomDecimalFormat {
static public String customFormat(String pattern, double value ) {
DecimalFormat myFormatter = new DecimalFormat(pattern);
String output = myFormatter.format(value);
return output;
}
}
but when I call the customFormat method like this: CustomDecimalFormat.customFormat("###.###,00") I get an exception...
What should I do?
Thanks!
Be sure to read and understand the Special Pattern Characters section of the Javadoc, especially this note:
The characters listed here are used in non-localized patterns. Localized patterns use the corresponding characters taken from this formatter's DecimalFormatSymbols object instead, and these characters lose their special status.
If you have done that, it should be clear to you that you must use the appropriate constructor and supply the appropriately configured separator/grouping chars, whereas in the pattern itself the dot and the comma have a special meaning.
All the complexity above is there for your convenience, actually: it allows you to customize the number format and have it localized.
Here's a code sample which worked for me:
final DecimalFormatSymbols syms = new DecimalFormatSymbols();
syms.setDecimalSeparator(',');
syms.setGroupingSeparator('.');
DecimalFormat myFormatter = new DecimalFormat("###,###.00", syms);
System.out.println(myFormatter.format(1234.12));
You can also use a variant where you apply the localized pattern, for more intuitive code:
final DecimalFormatSymbols syms = new DecimalFormatSymbols();
syms.setDecimalSeparator(',');
syms.setGroupingSeparator('.');
DecimalFormat myFormatter = new DecimalFormat("", syms);
myFormatter.applyLocalizedPattern("###.###,00");
System.out.println(myFormatter.format(1234.12));
First of all,
you misplaced the comma and decimal points. Your format should be : ###,###.00 instead of ###.###,00 ...
Also check with your Locale, it has an effect on the format. See the link below.
http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
You can try GERMAN number format
NumberFormat.getNumberInstance(Locale.GERMAN).format(102203345.32)
I have a monetary amount that is entered by a user and want to validate it. I have written a JSF validator but am having trouble getting this to work in all circumstances. Here is my scenario:
I have users in different Locales and therefore I need to cope with the various methods of input and want to allow the following
English
1234
1,234
1234.56
1,234.5
German & Spanish
1234
1.234
1234,56
1.234,5
French
1234
1 234
1234,56
1 234,5
My problem is with French as options 2 & 4 are seen as invalid using this code as the parsing stops at the space.
public void validate(final FacesContext pContext,
final UIComponent pComponent,
final Object pValue) {
boolean isValid = true;
final Locale locale = (Locale)pComponent.getAttributes().get(USERS_LOCALE);
final Currency currency = (Currency)pComponent.getAttributes().get(CURRENCY);
final NumberFormat formatter = NumberFormat.getNumberInstance(locale);
formatter.setGroupingUsed(true);
formatter.setMinimumFractionDigits(currency.getDefaultFractionDigits());
formatter.setMaximumFractionDigits(currency.getDefaultFractionDigits());
final ParsePosition pos = new ParsePosition(0);
final String stringValue = (String)pValue;
if (pos.getIndex() != stringValue.length() || pos.getErrorIndex() != -1) {
isValid = false;
}
...
I also want to ensure that the following are treated as invalid but they all parse successfully (except for French of course)
1,234,9.56 (Invalid grouping)
1,234.567 (too many decimal places for the currency)
Any help will be much appreciated
Ian
The French thousands' separator is actually a non-breaking space, \u00a0. If your input uses a regular space you can change the input:
input = input.replace(' ', '\u00a0');
Another thing you can do is change the grouping symbol to a regular space:
DecimalFormat decimalFormatter = (DecimalFormat) formatter;
DecimalFormatSymbols symbols = decimalFormatter.getDecimalFormatSymbols();
symbols.setGroupingSeparator(' ');
decimalFormatter.setDecimalFormatSymbols(symbols);
Can't recommend this, though. The new formatter won't accept numbers that use a non-breaking space as the grouping character.