java.lang.NumberFormatException: For input string: "1,167.40" [duplicate]
Asked Answered
J

5

11

I'm reading data from CSV file. One of the fields contains the value 1,167.40. The code piece for reading this field is the following:

String csvFilename = "TEST_FILE.csv";
CSVReader csvReader = new CSVReader(new FileReader(csvFilename));
String[] row = null;
csvReader.readNext(); // to skip the headers
while((row = csvReader.readNext()) != null) 
{
  double val = Double.parseDouble(row[0]); // !!!
}
csvReader.close();

The line double val = Double.parseDouble(row[0]) results in the following error message:

java.lang.NumberFormatException: For input string: "1,167.40"

How to solve this issue?

P.S. For other values like 111.64 this error does not appear.

Jahn answered 12/9, 2013 at 7:49 Comment(2)
Double.pareseDouble() does not like , in the strings you provide. Have you tried removing the , from the input? I assume 1,167.40 is the same as 1167.40.Odonto
I'm guessing NumberFormatException occurs cause of the comma(,). Try getting rid of it from the csv file.Virago
S
16

The error is in the comma , in the middle of your input. A quick dirty solution would be removing it before parsing it as a double.

double val = Double.parseDouble(row[0].replaceAll(",", ""));

The better solution is using a NumberFormat to handle this:

//assumes your server already has English as locale
NumberFormat nf = NumberFormat.getInstance(); /
//...
double val = nf.parse(row).doubleValue();
Sigismundo answered 12/9, 2013 at 7:52 Comment(5)
Replacing a value is really temporary solution as it would become very specific to data content. It rather make more sense to figure out the Locale and format the data first according to that.Giantess
And then attach a warning to your application "Does not work in France" ;-)Dunaj
@Dunaj if the pc/server is configured with English defaul locale then there's no problem.Sigismundo
For your second solution the compiler says "Cannot invoke doubleValue() on the primitive type double"Jahn
@KlausosKlausos thanks, code fixedSigismundo
D
7

You ought to use locale-specific formatting:

NumberFormat nf = NumberFormat.getInstance(Locale.ENGLISH);
myNumber = nf.parse(myString);

Some countries exchange the period and comma; ("1.167,40" in Locale.FRENCH, for example), so stripping the commas first is not safe.

Dunaj answered 12/9, 2013 at 7:53 Comment(1)
How to get double value?Jahn
G
4

It is because of character ',' (comma). The data here is represented for a specific locale. So you should use locale information to format the data in decimal first and then parse.

One such example is

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
public class JavaMain {
    public static void main(String[] args) {
        String numberString = "2.105,88";
        //using casting
        try {
            DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.GERMAN);
            df.setParseBigDecimal(true);
            BigDecimal bd = (BigDecimal) df.parseObject(numberString);
            System.out.println(bd.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
        try {
            BigDecimal bd1 = new BigDecimal(nf.parse(numberString).toString());
            System.out.println(bd1.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
Giantess answered 12/9, 2013 at 7:51 Comment(0)
D
3

Try

NumberFormat.getInstance().parse(row[0]) instead of Double.parseDouble()

Diplostemonous answered 12/9, 2013 at 7:53 Comment(0)
O
3

Double.parseDouble() does not like , in the strings you provide as parameter. Have you tried removing the , from the input? I assume 1,167.40 is the same as 1167.40.

You can try:

double val = Double.parseDouble(row[0].replace(',' , '');
Odonto answered 12/9, 2013 at 7:55 Comment(3)
No. No. No. Never strip the commas: you'll break continental European locales (France, Germany, etc).Dunaj
@Dunaj that's not the main problem here.Sigismundo
@Dunaj It is only passing the value to double, which you would have to do without coma anyway. replace returns a new string, so the original value of row[0], which I think should be used for locales, is not changed.Odonto

© 2022 - 2024 — McMap. All rights reserved.