java.lang.NumberFormatException: Invalid float: "٠" - java

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);

Related

How to use add dot in Java's DecimalFormat to currency?

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

Java - Format a String to show a pound sign and a decimal with two leading zeroes using objects and the toString method?

I have tried
System.out.println(myLorry.toString(registration, myCar.calcCharge()));
which outputs
Registration: TA17 NDD Charge: 7.0
I want my program to output
Registration: TA17 NDD Charge: £7.00
How can I format this correctly?
EDIT:
Why doesn't formatting work correctly? It says it's expecting two parameters but can only find one. I need to call objects using the toString method.
System.out.printf("%s £%.2f" ,myCar.toString(registration, myCar.calcCharge()));
like #davidxxx suggest in comment you can use
DecimalFormat d = new DecimalFormat("'£'0.00");
System.out.println(d.format(7.0));
Output
£7,00
If you have a problem with dot(.) and comma(,) then you can use DecimalFormatSymbols :
DecimalFormat d = new DecimalFormat("'£'0.00");
DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance();
sym.setDecimalSeparator('.');
d.setDecimalFormatSymbols(sym);
one solution is to use the printf.
e.g.
double value = 7.0;
System.out.printf("%s%.2f","£", value);
output:
£7.00
In fact you should consider two things :
formatting the number value with the fixed number of digits for the floating part.
setting the decimal separator character.
The second point may matter as according to the locale set by the JVM, you could get a distinct result : £7.00 or £7,00
So, you could specify the "£0.00" pattern in DecimalFormat and create the DecimalFormat instance with a specific DecimalFormatSymbols that ensures that you will use as decimal symbol the . character.
You could do it for example :
float f = 7;
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
otherSymbols.setDecimalSeparator('.');
NumberFormat formatter = new DecimalFormat("£0.00", otherSymbols);
String valueFormated = formatter.format(f);
But in fact a more simple way would be to use the String.format() method by specifying both the expected pattern (two digits for the floating part) and a Locale that uses the . as decimal separator :
float f = 7;
String valueFormated = String.format(Locale.US, "£%.2f", f);
Solved it! I was looking in completely the wrong part of my program, here is my solution:
String toString(String rn, double calcCharge)
{
DecimalFormat d = new DecimalFormat("£0.00");
return "Registration: " + rn + " Charge: " + d.format(calcCharge());
}
I had to modify a class that my subclasses inherited from.

How to make a string from a BegDecimal number which contained only the integral part

My question is about of toString() and toPlainString() methods of the BigDecimal dataTypewhich produces the output like
750.0000
150.0000
... etc
My question is how to specify the number of zeros followed after the dot? Is there a way to do it instead of String.replace(".0000", ".00") method?
Use DecimalFormat in combination with DecimalFormatSymbols:
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setDecimalSeparator('.');
DecimalFormat df = new DecimalFormat("##.##");
df.setDecimalFormatSymbols(dfs);
df.format(myNumber)
Without using DecimalFormatSymbols you would end up with a comma as a decimal seperator instead.
Please use the below code.
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);
String s = nf.format(1111.2222);
System.out.println(s);
Apart from decimal format you can also use setScale(2) like this
new BigDecimal("1.0000").setScale(2)
Also setScale allows you can specify the Rounding Mode
You could use setScale method and optinally you could choose rounding methodology of your own. Somethign like:
BigDecimal b = new BigDecimal("750.0000");
b.setScale(2);

Java NumberFormat isn't respecting comma as decimal separator

I found a bug in my app where my currency strings were not showing the correct grouping and decimal separators when using an international format. I extracted the code to try to isolate and demonstrate the problem. In the code below, I create a US formatter and a World formatter. They both use the same currency pattern, but the USA formatter uses a period as the decimal separator and the World formatter uses a comma as the decimal separator.
When I ask the World formatter to tell me what its separators are, it reports them correctly. However, when I have it generate the string for my value, it doesn't do it properly. It strangely uses the period for both the grouping AND the decimal separator.
public static void main(String[] args) throws Exception {
String currencyFormat = "¤#,##0.00;-¤#,##0.00";
NumberFormat currencyUSA = NumberFormat.getCurrencyInstance();
DecimalFormat decimalCurrencyUSA = (DecimalFormat)currencyUSA;
decimalCurrencyUSA.applyPattern(currencyFormat);
NumberFormat currencyWorld = NumberFormat.getCurrencyInstance();
DecimalFormat decimalCurrencyWorld = (DecimalFormat)currencyWorld;
decimalCurrencyWorld.applyPattern(currencyFormat);
DecimalFormatSymbols decimalFormatSymbols = decimalCurrencyWorld.getDecimalFormatSymbols();
//DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(Locale.GERMAN);
System.out.println(String.format("Original grouping: %c decimal: %c", decimalFormatSymbols.getGroupingSeparator(), decimalFormatSymbols.getDecimalSeparator()));
decimalFormatSymbols.setDecimalSeparator(',');
decimalFormatSymbols.setGroupingSeparator('.');
decimalCurrencyWorld.setDecimalFormatSymbols(decimalFormatSymbols);
System.out.println(String.format(" After grouping: %c decimal: %c", decimalFormatSymbols.getGroupingSeparator(), decimalFormatSymbols.getDecimalSeparator()));
String moneyUSA = currencyUSA.format(1500.75);
String moneyWorld = currencyWorld.format(1500.75);
DecimalFormatSymbols decimalFormatSymbols2 = decimalCurrencyWorld.getDecimalFormatSymbols();
System.out.println(String.format(" Real grouping: %c decimal: %c", decimalFormatSymbols2.getGroupingSeparator(), decimalFormatSymbols2.getDecimalSeparator()));
System.out.println(String.format(" USA String: %s", moneyUSA));
System.out.println(String.format("World String: %s", moneyWorld));
Number numberUSA = currencyUSA.parse(moneyUSA);
Number numberWorld = currencyWorld.parse(moneyWorld);
System.out.println(String.format(" USA Number: %f", numberUSA));
System.out.println(String.format("World Number: %f", numberWorld));
}
When I run the above code (on my Mac OS X 10.9, Eclipse Indigo, Java 1.6), the output is:
Original grouping: , decimal: .
After grouping: . decimal: ,
Real grouping: . decimal: ,
USA String: $1,500.75
World String: $1.500.75
USA Number: 1500.750000
World Number: 1.500000
The World currency value should be $1.500,75 however it used a period in both places.
EDIT:
I need to control the separators specifically. I can respect the user's Locale when it comes to the currency symbol, but due to the requirements of this app, I need to provide the user the ability to swap the period/comma when it comes to the separators. I can't just rely on the Locale to control these things.
The problem is that I'm clearly setting those values in my formatters and they aren't being respected.
EDIT 2: I added code to then parse the previously generated money string to see if the Decimal separators were being respected for parsing, but not for formatting. It appears that during parsing, the period is still being treated as the decimal separator as well because the World Number came out as 1.5 instead of 1500.75.
From Customizing Formats
¤ currency sign; replaced by currency symbol; if doubled, replaced by international currency symbol; if present in a pattern, the monetary decimal separator is used instead of the decimal separator
So:
decimalFormatSymbols.setMonetaryDecimalSeparator(',');
Will do it.
If you change
DecimalFormatSymbols decimalFormatSymbols = decimalCurrencyWorld.getDecimalFormatSymbols();
to
DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(Locale.GERMAN);
(or some other Locale) you will find that the separators work properly.
decimalFormatSymbols.setDecimalSeparator(','); apparently does not change the format (although setGroupingSeparator() does, as you have discovered).

Formatting in java

Good day.
I need to format a number in java.
So far I have this:
DecimalFormat df2 = new DecimalFormat( "#,###,###,##0.00" );
System.out.println(new Double(df2.format(balance)).doubleValue());
But it prints out this
110.0
121.0
133.1
146.41
161.05
But I need it to be with two digits in fraction part. How do I do it?
You don't have to get double value from formatted string.
Just use formatted string, which is returned from format() method of DecimalFormat.
So your code should be like the following:
DecimalFormat df2 = new DecimalFormat( "#,###,###,##0.00" );
...
System.out.println(df2.format(balance));
Your original code:
System.out.println(new Double(df2.format(balance)).doubleValue());
What you did in your code is: format the double value to string(which is formatted as you specified in the DecimalFormat instance). Then you convert the formatted string to Double instance and get double value from the object, which is double. And then printed it to console. So the formatted string is gone, and the double value is printed as normal.
"But I need it to be with two digits in fraction part. How do I do it?"
DecimalFormat df2 = new DecimalFormat( );
df2.setMinimumFractionDigits(2);
df2.setMaximumFractionDigits(2);
System.out.println(df2.format(balance));
You could also use the setMinimumFractionDigits method of DecimalFormat
df2.setMinimumFractionDigits(2);
your decimal format is right, but
what you are doing before you print this out is new Double(df2.format(balance)) which create new instant of double, which ignores your formatting.
so if you want to display or log your value df2.format(balance) this should be enough
ie:
System.out.println(df2.format(balance));
Try this pattern for formatting #,###,###,##.##-
DecimalFormat df2 = new DecimalFormat( "#,###,###,##.##" );
System.out.println(df2.format(balance));
This should be sufficient:
DecimalFormat df2 = new DecimalFormat("#,##0.00");
System.out.println(df2.format(balance));
The grouping for separator will follow "the interval between the last one and the end of the integer". So there is no benefit from over-specify. Example from the documentation of DecimalFormat:
The grouping separator is commonly used for thousands, but in some countries it separates ten-thousands. The grouping size is a constant number of digits between the grouping characters, such as 3 for 100,000,000 or 4 for 1,0000,0000. If you supply a pattern with multiple grouping characters, the interval between the last one and the end of the integer is the one that is used. So "#,##,###,####" == "######,####" == "##,####,####".
Another thing is that .format() method already output a String, so there is no point in converting it to double. It will cause Exception to be thrown when balance is more than 1000 (the point when separator comes into effect, and Double class cannot parse the String with separator).

Categories

Resources