Parsing from String to double, different on different platforms

P

Peter the Swede

When you want to parse a String to a double, it seems like Java is sensitive
if the decimaloperator is a '.' or a ',' (dot or comma). On my platform ','
(comma) is the right one. I don't want to have that problem, I want it to
accept both. Is there any other way than to write your own Parsing class
that handels the Parsing.

Cheers, Peter
 
A

Anton Spaans

Hi Peter,

Use the NumberFormat class and create one for the specified locale (whether
decimaloperater is a '.' or a ',' depends on the locale (see the Locale
class)). It depends whether the locale is, for example, german (e.g. 23,4)
or american (e.g 23.4).

So, do:

String strValue = ...

NumberFormat fmt = NumberFormat.getInstance();
Number number = fmt.parse(strValue);

double dValue = number.doubleValue();

If you know that the strValue comes from user-input from a different locale
than your system ( e.g. from a browser in another country), get the user's
locale and then replace one of the lines with this:

NumberFormat fmt = NumberFormat.getInstance(userLocale);
 
N

nos

In Saudi Arabia there is no decimal, rather "SR"
is appended so you example would be "2340SR"
(normally the US penny equates to one SR)
At least this was the case when I developed some
software 20 years ago.
Does locale take care of this too?
 
T

Tony Dahlman

nos said:
In Saudi Arabia there is no decimal, rather "SR"
is appended so you example would be "2340SR"
(normally the US penny equates to one SR)
At least this was the case when I developed some
software 20 years ago.
Does locale take care of this too?

Well, that's currency, not decimal, isn't it? In theory
you could just plug in the Saudi locale and everything would
be right....

But my look at the 1.4.2 API doesn't show Saudi Arabia
as a "valid" Locale. Maybe Sun should add a few Locale(s)....

I have no idea what is taught to Saudi elementary students,
but most of Europe and lots of Latin America use a comma
for the decimal separator, and a dot for the grouping
separator.

Anyway, the algorithm Java uses for deciding currency and
decimal identifiers (based on language/country locales)
works as well as anything out there, maybe because it was
"adopted" from Unix.

Tony Dahlman
 
R

Roedy Green

When you want to parse a String to a double, it seems like Java is sensitive
if the decimaloperator is a '.' or a ',' (dot or comma). On my platform ','
(comma) is the right one. I don't want to have that problem, I want it to
accept both. Is there any other way than to write your own Parsing class
that handels the Parsing.

You could just convert the . to , (or vice versa) prior to conversion
with String.replace
 
P

Peter the Swede

I've done that temporary, but that is not a solution for developing
something that is supposed to work anywhere, on any platform.

Cheers, Peter
 
P

Peter the Swede

package golf.gui;

import java.text.NumberFormat;

import java.text.ParsePosition;



public class Parse {

private static NumberFormat myForm = NumberFormat.getInstance();


public static void setFormat(NumberFormat aForm) {

myForm = aForm;

}


public static int toInt(String aString) {

return Integer.parseInt(aString.trim());

}


public static double toDouble(String aString) {

ParsePosition p = new ParsePosition(0);

myForm.setGroupingUsed(false);

Number n = myForm.parse(aString.trim(), p);

if(n == null || p.getIndex() != aString.length()) {


throw new NumberFormatException();

}

return n.doubleValue();

}

}



This is the class that I used for converting that was throwing
NumberFormatException. I have temoporary modified the String that comes in
so it uses my standard, but I will try the change that you suggested.

Cheers, Peter
 
T

Thomas G. Marshall

Hi Peter,

Use the NumberFormat class and create one for the specified locale
(whether decimaloperater is a '.' or a ',' depends on the locale (see
the Locale class)). It depends whether the locale is, for example,
german (e.g. 23,4) or american (e.g 23.4).

So, do:

String strValue = ...

NumberFormat fmt = NumberFormat.getInstance();
Number number = fmt.parse(strValue);

double dValue = number.doubleValue();

If you know that the strValue comes from user-input from a different
locale than your system ( e.g. from a browser in another country),
get the user's locale and then replace one of the lines with this:

NumberFormat fmt = NumberFormat.getInstance(userLocale);

Yes, and it should be pointed out that you should /almost always/ use number
format parsing in the very common case of user input (from anywhere). And
users are likely to enter /anything/ that they are accustomed to. Unless of
course performance is at a premium, in which case you've got to enforce what
you're parsing.

You don't want your program failing because of a rogue comma.

And FURTHERMORE, you really don't want to specifically parse for a comma, or
your program just might fail in the UK someday. NumberFormat uses a default
local which is appropriate for the local country, assuming that the JRE or
browser was installed correctly.
 
N

nos

oops, you're right

Tony Dahlman said:
Well, that's currency, not decimal, isn't it? In theory
you could just plug in the Saudi locale and everything would
be right....

But my look at the 1.4.2 API doesn't show Saudi Arabia
as a "valid" Locale. Maybe Sun should add a few Locale(s)....

I have no idea what is taught to Saudi elementary students,
but most of Europe and lots of Latin America use a comma
for the decimal separator, and a dot for the grouping
separator.

Anyway, the algorithm Java uses for deciding currency and
decimal identifiers (based on language/country locales)
works as well as anything out there, maybe because it was
"adopted" from Unix.

Tony Dahlman
 
T

Thomas G. Marshall

Roedy Green said:
You could just convert the . to , (or vice versa) prior to conversion
with String.replace

A disasterous idea if your app stands a chance of running anywhere where
that substitution rule might not apply. Depending upon the expected venue,
you could get away with it if you Knew For Sure (tm). But in this world,
anyone, anywhere, is running most everything.
 
R

Roedy Green

A disasterous idea if your app stands a chance of running anywhere where
that substitution rule might not apply. Depending upon the expected venue,
you could get away with it if you Knew For Sure (tm). But in this world,
anyone, anywhere, is running most everything.

You can generate the correct substitution rule by using
DecimalFormatSymbols.getDecimalSeparator and getGroupingSeparator.

Unfortunately , . are reversed to . , in Sweden. Code to accept both
has to do some guesswork which convention is being used. E.g. is
8,888 supposed to be a number around 9000 or around 9? That's is
likely why DecimalFormat accepts only one scheme at a time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top