I'm making an Android Java program which is taking double values from the user. If I run the program on the computer, it works great because of the locale of my computer, EN_UK. But when I run it on my mobile phone with FI_FI locale, it won't work. I know the reason: In UK, people use dot as decimal separator but here in Finland, the decimal separator is comma.
DecimalFormat df = new DecimalFormat("#.#");
Double returnValue = Double.valueOf(df.format(doubleNumber));
When I'm using comma, it says java.lang.NumberFormatException: Invalid double: "1234,5".
How can I make it work with them both, comma and dot?
Use one of the other constructors of DecimalFormat:
new DecimalFormat("#.#", new DecimalFormatSymbols(Locale.US))
And then try and parse it using both separators.
using DecimalFormatSymbols.getInstance() will produce the default locale's correct symbols, so you will get it right for any platform you run on.
DecimalFormat df = new DecimalFormat("#.#", DecimalFormatSymbols.getInstance());
This should work for both Java(Tested) as well as android :)
Class Name: In18Helper.java
package com.akmeher.app.utils;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
public class In18Helper {
private final static In18Helper mHelper = new In18Helper();
public static final In18Helper getInstance() {
return mHelper;
}
public double getDouble(String sValue, Locale locale) {
NumberFormat numberFormat = NumberFormat.getInstance(locale);
Number parse = null;
try {
parse = numberFormat.parse(sValue);
} catch (ParseException e) {
e.printStackTrace();
}
return parse == null ? 0 : parse.doubleValue();
}
}
Class Name: Application.java
package com.akmeher.app;
import java.util.Locale;
import com.akmeher.app.utils.In18Helper;
public class Application {
static DataModel[] testData = new DataModel[] {
new DataModel("1.034567", Locale.ENGLISH),
new DataModel("1,0345.67", Locale.ENGLISH),
new DataModel("1.0345,67", Locale.GERMANY),
new DataModel("1,034,567", Locale.CANADA),
new DataModel("1.034567", Locale.KOREA),
new DataModel("1,03.4567", Locale.ITALY) };
/**
* #param args
*/
public static void main(String[] args) {
for (int i = 0; i < testData.length; i++) {
double d = In18Helper.getInstance().getDouble(testData[i].mValue,
testData[i].mLocale);
System.out.println("Trial Value: "+testData[i].mValue+" for Locale: "+testData[i].mLocale+" converted to: "+d);
}
}
private static class DataModel {
String mValue;
Locale mLocale;
public DataModel(String value, Locale locale) {
this.mLocale = locale;
this.mValue = value;
}
}
}
Output:
Trial Value: 1.034567 for Locale: en converted to: 1.034567
Trial Value: 1,0345.67 for Locale: en converted to: 10345.67
Trial Value: 1.0345,67 for Locale: de_DE converted to: 10345.67
Trial Value: 1,034,567 for Locale: en_CA converted to: 1034567.0
Trial Value: 1.034567 for Locale: ko_KR converted to: 1.034567
Trial Value: 1,03.4567 for Locale: it_IT converted to: 1.03
Hope this will help somebody to make use of.
public static Double parseDoubleTL(String value){
DecimalFormat df = new DecimalFormat("#.#", new DecimalFormatSymbols(new Locale("tr_TR")));
Double doublePrice = 0.0;
try {
doublePrice = df.parse(value).doubleValue();
} catch (ParseException e) {
Log.w(MainActivity.TAG,"Couldnt parse TL. Error is "+e.toString());
}
return doublePrice;
}
Not a best way but worked for me;
Double val=null;
try{
val=Double.valueOf(value);
}catch(Exception e){
val=Double.valueOf(value.replace(',','.'));
}
Double val=null;
try{
val=Double.valueOf(value);
}catch(Exception e){
val=Double.valueOf(value.replace(',','.'));
}
return val;
Me Error:
java.lang.NumberFormatException: Invalid float: "1,683.88"
... and this work for me
replace(",", "")
DecimanFormat df = new DecimalFormat("#.#");
Related
I'm using NumberFormat in my app to get the currency formatted Strings. Like if a user inputs 12.25 in the field then it will be changed to $12.25 based on locale. Here the Locale is en-US.
Now I want to get the 12.25 value as double form the formatted string.
To do that I have used:
NumberFormat.getCurrencyInstance().parse("$12.25").doubleValue();
Above line giving me the result of 12.25 which is my requirement. But suppose a user changed his locale to something else en-UK. Now for that locale above statement is giving me parseException. Because for the locale en-UK, currency string $12.25 is not parsable.
So is there any way to get the double value from currency formatted string irrespective of what the locale is?
I don't know either the below solution is perfect or not but it is working according to my requirement.
try {
return NumberFormat.getCurrencyInstance().parse(currency).doubleValue();
} catch (ParseException e) {
e.printStackTrace();
// Currency string is not parsable
// might be different locale
String cleanString = currency.replaceAll("\\D", "");
try {
double money = Double.parseDouble(cleanString);
return money / 100;
} catch (Exception ex) {
ex.printStackTrace();
}
}
return 0;
What about
new Double(NumberFormat.getCurrencyInstance().parse("$12.25").doubleValue());
and also you could use
Double.valueOf() creates a Double object so .doubleValue() should not be necessary.
also Double.parseDouble(NumberFormat.getCurrencyInstance().parse("$12.25"));
could work
Here's a little algorithm that may help you :
public static void main(String[] args) {
String cash = "R$1,000.75"; //The loop below will work for ANY currency as long as it does not start with a digit
boolean continueLoop = true;
char[] cashArray = cash.toCharArray();
int cpt = 0;
while(continueLoop){
try
{
double d = Double.parseDouble(cashArray[cpt]+"");
continueLoop = false;
}catch(NumberFormatException nfe){
cpt += 1;
}
}
System.out.println(cpt);
//From here you can do whatever you want....
String extracted = cash.substring(cpt);
NumberFormat format = NumberFormat.getInstance(Locale.US); //YOUR REQUIREMENTS !!!! lol
try {
Number youValue = format.parse(extracted);
System.out.println(youValue.doubleValue());
} catch (ParseException ex) {
//handle your parse error here
}
}
You should get as result here in the output:
2
1000.75
I am working on an Android app, and I am getting the most annoying NFE for, what seems like, no reason.
So, here is what I have in my app:
int amount = 7;
NumberFormat myNumberFormat = NumberFormat.getCurrencyInstance(Locale.US);
TextView money = (TextView)findViewById(R.id.money_view);
money.setText(myNumberFormat.format(amount));
And for some reason, I am getting a NFE when I try to get the NumberFormat currency instance. As a test, to make sure I wasn't going crazy, I also wrote this stand-alone:
import java.util.Locale;
import java.text.NumberFormat;
public class NFETest {
public static void main(String[] args){
int amount = 7;
NumberFormat myNumberFormat = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(myNumberFormat.format(amount));
}
}
The stand-alone works with no problems. So, what gives ... why am I getting this error?
EDIT:
Looking further down LogCat, it looks like it is an IllegalArgumentException instead of a NFE. However, this doesn't make it any less strange. I have "Locale.US" set, so that shouldn't make any difference. However, some quick googling says it may be my tablet thinking it is not in the US. It may be a hardware issue, and not software after all.
Use this code
int amount = 7;
NumberFormat myNumberFormat = NumberFormat.getCurrencyInstance(Locale.US);
TextView money = (TextView)findViewById(R.id.money_view);
money.setText(String.valueOf(myNumberFormat.format(amount)));
Just use wrappers(Integer, Float, Double, BigDecimal or others):
public static void main(String[] args){
Integer amount = 7;
NumberFormat myNumberFormat = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(myNumberFormat.format(amount));
int amount2 = 11;
System.out.println(myNumberFormat.format(Integer.valueOf(amount2)));
}
In other solution, you may use Integer.valueOf(..) Look like here: http://ideone.com/0ZKsS3
But your example works too. Look at online compiler: http://ideone.com/0ZKsS3
try {
int amount = 7;
NumberFormat myNumberFormat = NumberFormat.getCurrencyInstance(Locale.US);
TextView money = (TextView)findViewById(R.id.money_view);
money.setText(String.valueOf(myNumberFormat.format(amount)));// your error is here.
//go on as normal
} catch (NumberFormatException e) {
//handle error
}
you should catch the exception and handle the parse error accordingly.
Or you should try for different values :
double num = 1323.526;
NumberFormat defaultFormat = NumberFormat.getCurrencyInstance();
System.out.println("US: " + defaultFormat.format(num));
Locale swedish = new Locale("sv", "SE");
NumberFormat swedishFormat = NumberFormat.getCurrencyInstance(swedish);
System.out.println("Swedish: " + swedishFormat.format(num));
OUTPUT :
US: $1,323.53
Swedish: 1 323,53 kr
Hope this time it will help you to catch your problem.
Trying to figure out why the following code is not outputting expecting results. Please advise. Thank you.
import java.text.*;
public class Test {
public static void main(String[] args) {
String s = "987.123456";
double d = 987.123456d;
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(5);
System.out.println(nf.format(d) + " ");
try {
System.out.println(nf.parse(s));
} catch (Exception e) {
System.out.println("got exc");
}
}
}
Output:
987.12346 // Expected 987.12345 not 987.12346
987.123456
Your second print doesn't format the double you've parsed.
// System.out.println(nf.parse(s));
System.out.println(nf.format(nf.parse(s))); // <-- 987.12346
To get the output you asked for, you can add a call to NumberFormat#setRoundingMode(RoundingMode) - something like
nf.setMaximumFractionDigits(5);
nf.setRoundingMode(RoundingMode.DOWN);
I've been trying to use java.text.DecimalFormat to validate user input of decimal numbers. I know the maximum number of digits both before and after the decimal place that are to be allowed - if there are more of either, that's an input error by the user. It seems like setMaximumIntegerDigits() is not being enforced though. (Or if I use a pattern, rather than the min/max setters, the maximum digits implied by the pattern seem again to be ignored.)
What am I missing?
(Apologies if this is a duplicate. I can find a lot of questions about DecimalFormat on SO - but none that seem to be quite this problem.)
Here's the sample code and a unit test (distilled from real code):
---- Numbers.java
/** Utility for creating and using a standard DecimalFormat. */
package com.myco.util;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParsePosition;
public final class Numbers {
private Numbers() { ; }
public static DecimalFormat standardFormat() {
DecimalFormat df = new DecimalFormat();
df.setParseBigDecimal(true);
df.setMaximumIntegerDigits(3);
df.setMinimumIntegerDigits(1);
df.setMaximumFractionDigits(2);
df.setMinimumFractionDigits(0);
return df;
}
// Alternatively, approach, also doesn't work.
/*public static DecimalFormat standardFormat() {
DecimalFormat df = new DecimalFormat("##0.##");
df.setParseBigDecimal(true);
return df;
}*/
public static BigDecimal match(DecimalFormat df, String s)
throws NumberFormatException {
if(s == null || (s = s.trim()).length() == 0)
return null;
ParsePosition pp = new ParsePosition(0);
Number n = df.parse(s, pp);
if(n == null || pp.getIndex() != s.length())
throw new NumberFormatException(
"Invalid BigDecimal for format '"+df+"'!");
return BigDecimal.class.cast(n);
}
}
By my reading of the Javadoc for DecimalFormat the test for 1000 (below) should pass
(that is, it should throw an exception) but it doesn't.
http://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html
---- Numbers_Test.java
package com.myco.util;
import java.text.DecimalFormat;
import junit.framework.TestCase;
public final class Numbers_Test extends TestCase {
public void testOkay() {
DecimalFormat df = Numbers.standardFormat();
assertEquals("0.1", Numbers.match(df, "0.1").toString());
assertEquals("4.2", Numbers.match(df, "4.2").toString());
assertEquals("999.99", Numbers.match(df, "999.99").toString());
}
public void testFail() {
DecimalFormat df = Numbers.standardFormat();
try {
// Returns 1000 (as BigDecimal) but should fail (?).
Numbers.match(df, "1000");
fail();
}
catch(NumberFormatException e) { ; }
}
}
i try to save my String value (50000000) into Double format, while I'm trying to show it again in my Edittext, I can't to show it in normal format, and it show as (5E+07), is there any way to convert from double format into String format?
I have try this way :
Double value_doble = 5E+07;
EditText.setText(String.valueOf(value_doble);
but its Still show as 5E+07, so my question how to convert from Double to String?
You can try this:
System.out.println(new BigDecimal(value_doble).toString());
Is this what you are looking for?
public static void main(String[] args) {
Double value_doble = 5E+07;
NumberFormat formatter = new DecimalFormat("###.#####");
String f = formatter.format(value_doble);
System.out.println(f);
}
I agree that you need use Formater
http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
but the pattern should be look like this:
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class DoubleFormat {
public static void main(String[] args) {
double valueD = 5E+07;
NumberFormat format = new DecimalFormat("#");
System.out.println(format.format(valueD));
}
}