I want to be able to convert a string to a Double given a number of decimal places in a format string. So "###,##0.000" should give me a Double to 3 decimal places.
Edit - added more info to what happens
The user enters the value in the UI - which is input into a String. The rule is this value is limited to 3 decimal places. The underlying code stores the value in the database which is then used in a calculation. Therefore the trailing decimal places will cause the calculations to be out slightly to what would be expected.
I have the following code:
try {
// output current locale we are running under (this happens to be "nl_BE")
System.out.println( "Current Locale is " + Locale.getDefault().toString() );
// number in Central European Format with a format string specified in UK format
String numberCE = "1,234567"; // 1.234567
String formatUK = "###,##0.000";
// do the format
DecimalFormat formatterUK = new DecimalFormat( formatUK );
Double valCEWithUKFormat = formatterUK.parse( numberCE ).doubleValue();
// I want the number to DPs in the format string!!!
System.out.println( "CE Value " + numberCE + " in UK format (" + formatUK + ") is "
+ valCEWithUKFormat );
} catch( ParseException ex ) {
System.out.println("Cannot parse number");
}
}
The DecimalFormat seems to ignore the format string and gives me the complete string as a Double of 1.234567.
Can DecimalFormat be forced to use the format string when parsing? Am I missing something?
Cheers,
Andez
Sure you can. Try running this:
Clearly they result in different output, the first reading
1.234567
and the second1234567
. Maybe there's something wrong with your pattern? Anyway the last line there would be the preferred way of getting theUK
standard format.The restriction of decimal places in DecimalFormat is really meant for use in the
format()
method and doesn't have much effect in theparse()
method.In order to get what you want you need this:
You first need to get the number as a UK format string and then parse that number, using the UK formatter. That will get you the result you're looking for. NB, this will round the number to 3 decimal places, not truncate.
By the way, I'm slightly surprised that your UK formatter is able to parse the CE format number. You really should be parsing the original number with a CE format parser.
Taking on board what you said I have modified my code slightly to cover different locales. The key was taking a value string in a localised format to a Double that is rounded based on the format string.
The format string is always a UK based format with the decimal seperators specified as "." and thousand seperators specified as ",".
I am using the DecimalFormat to initially parse the localised format based on a specified locale. This gives a Double equivalent of the string correctly. I then use a BigDecimal to handle the rounding. I can get the number of decimal places from the DecimalFormat instance and call setScale on the BigDecimal to perform the rounding.
The initial code structure has been modified to allow you to see what happens under different locale circumstances thanks @RD01 for noting importance of other locales.
I now have code as follows:
This produces the following output:
DecimalFormat is used for two distinct purposes: parsing input and formatting output. If you want to do both, you'll have to use the format object twice.
If you want to take that value and format the output, restricting the number of significant digits, you need to use the format object again. This time it uses your formatting rules to create an output string from a numeric value:
This will give you the output of
1,235
It seems you want this numeric value to be presented in the 1.235 format. To do this, you should format the output using a specific locale (if yours uses a different format).
HOWEVER, I would recommend approaching this problem differently:
A few notes: