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:
private void runTests3() {
// output current locale we are running under
System.out.println( "Current Locale is " + Locale.getDefault().toString() );
// number in Central European Format with a format string specified in UK format
String numbersInEuropeanFormatString[] = new String[] { "1.000,234567", "1,2345678", "1.222.333,234567" };
String formatUK = "###,##0.0000";
// output numbers using the german locale
System.out.println("Output numbers using the German locale\n");
for(String num : numbersInEuropeanFormatString ) {
formatNumberAsDouble(num, formatUK, Locale.GERMAN);
}
// output numbers using the UK locale.
// this should return unexpected results as the number is in European format
System.out.println("Output numbers using the UK locale\n");
for(String num : numbersInEuropeanFormatString ) {
formatNumberAsDouble(num, formatUK, Locale.UK);
}
// output numbers using new DecimalFormat( formatUK ) - no locale specified
System.out.println("\n\nOutput numbers using new DecimalFormat( " + formatUK + " )\n");
for(String num : numbersInEuropeanFormatString ) {
formatNumberAsDouble( num, formatUK, null);
}
}
private void formatNumberAsDouble(String value, String format, Locale locale) {
NumberFormat formatter;
int decimalPlaces;
// create the formatter based on the specified locale
if( locale != null ) {
formatter = NumberFormat.getNumberInstance(locale);
// creating the above number format does not take in the format string
// so create a new one that we won't use at all just to get the
// decimal places in it
decimalPlaces = (new DecimalFormat(format)).getMaximumFractionDigits();
} else {
formatter = new DecimalFormat( format );
decimalPlaces = formatter.getMaximumFractionDigits();
}
// get the result as number
Double result = null;
try {
result = formatter.parse( value ).doubleValue();
} catch( ParseException ex ) {
// not bothered at minute
}
// round the Double to the precision specified in the format string
BigDecimal bd = new BigDecimal(result );
Double roundedValue = bd.setScale( decimalPlaces, RoundingMode.HALF_UP ).doubleValue();
// output summary
System.out.println("\tValue = " + value);
System.out.println( locale == null ? "\tLocale not specified" : "\tLocale = " + locale.toString());
System.out.println( format == null || format.length() == 0 ? "\tFormat = Not specified" : "\tFormat = " + format);
System.out.println("\tResult (Double) = " + result);
System.out.println("\tRounded Result (Double) (" + decimalPlaces + "dp) = " + roundedValue);
System.out.println("");
}
This produces the following output:
Current Locale is nl_BE
Output numbers using the German locale
Value = 1.000,234567
Locale = de
Format = ###,##0.0000
Result (Double) = 1000.234567
Rounded Result (Double) (4dp) = 1000.2346
Value = 1,2345678
Locale = de
Format = ###,##0.0000
Result (Double) = 1.2345678
Rounded Result (Double) (4dp) = 1.2346
Value = 1.222.333,234567
Locale = de
Format = ###,##0.0000
Result (Double) = 1222333.234567
Rounded Result (Double) (4dp) = 1222333.2346
Output numbers using the UK locale
Value = 1.000,234567
Locale = en_GB
Format = ###,##0.0000
Result (Double) = 1.0
Rounded Result (Double) (4dp) = 1.0
Value = 1,2345678
Locale = en_GB
Format = ###,##0.0000
Result (Double) = 1.2345678E7
Rounded Result (Double) (4dp) = 1.2345678E7
Value = 1.222.333,234567
Locale = en_GB
Format = ###,##0.0000
Result (Double) = 1.222
Rounded Result (Double) (4dp) = 1.222
Output numbers using new DecimalFormat( ###,##0.0000 )
Value = 1.000,234567
Locale not specified
Format = ###,##0.0000
Result (Double) = 1000.234567
Rounded Result (Double) (4dp) = 1000.2346
Value = 1,2345678
Locale not specified
Format = ###,##0.0000
Result (Double) = 1.2345678
Rounded Result (Double) (4dp) = 1.2346
Value = 1.222.333,234567
Locale not specified
Format = ###,##0.0000
Result (Double) = 1222333.234567
Rounded Result (Double) (4dp) = 1222333.2346