2

Somewhat related to this question and several other SO questions relating to formatting decimals (all of which did not help me in this instance).

I am trying to format a Long into a String e.g. 123456 -> 012.345,6 (period followed by comma as strange as it may seem, it's a project requirement).

I am experimenting with DecimalFormat for the formatting:

private static final DecimalFormat format = new DecimalFormat("##0.000,0");

However it throws an exception during instantiation:

java.lang.IllegalArgumentException: Malformed pattern "##0.000,0"

I have also experimented with changing the locale to an EU system beforehand e.g.

NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.GERMAN);

How can I format numbers in this way? Is DecimalFormat the wrong solution? Can I use a NumberFormat? Or will I need a custom formatter?

Community
  • 1
  • 1
glenneroo
  • 1,908
  • 5
  • 30
  • 49

5 Answers5

7

You should avoid constructing DecimalFormat directly. Commas are always used for grouping in the pattern definition, regardless of how they appear in the target locale. Similarly, periods are always used for decimals. This appears illogical, but one must remember this is a pattern definition, and like #, these characters describe a replacement, not the character itself.

NumberFormat f = NumberFormat.getInstance(Locale.GERMANY);
if (f instanceof DecimalFormat) {
    ((DecimalFormat) f).applyPattern("##0,000.0");
}
f.format(123456 / 10.0);

The division by 10 is necessary to obtain a digit after the decimal point.

David Grant
  • 13,929
  • 3
  • 57
  • 63
1

http://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html

let's try this

new DecimalFormat("0##,###.0");

remember, commas are delimiters, points are fractions. You cannot switch those two around.

This format will print the leading zero, two important digits, then three digits, then the fraction or 0 if it's a round number. I think.

So, the best you can get is 123456-> 012,345.6

workaround:

int index1 = string.indexOf(',');
int index2 = string.indexOf('.');
string.setCharAt(index1, '.');
string.setCharAt(index2, ',');
Shark
  • 6,513
  • 3
  • 28
  • 50
  • You are assuming I am working with normal numbers ;) I guess I need a different (custom?) formatter because a project requirement is to actually have a period first followed by comma, as strange as it may seem. – glenneroo Oct 03 '12 at 15:36
  • 1
    i know that's how we do it in europe but it looks like you'll just have to roll your own one... or... switch places of PERIOD and COMMA after you format it like this. – Shark Oct 03 '12 at 15:38
1

Sorry if I am missing your request, but if you need a non-standard number representation then you can write a formatter simply enough:

static String formatLong(long value) {
        String ret = Long.toString(value);

        // Make the value 7 digits by prepending 0's
        while(ret.length()<7) ret="0"+ret;

        // Add a comma before the last digit
        ret = ret.substring(0,ret.length()-1)+","+ret.substring(ret.length()-1);

        // Add a period before the 4th digit
        ret = ret.substring(0,ret.length()-5)+"."+ret.substring(ret.length()-5);

        return ret;
    }

long a = 123456;
System.out.println(formatLong(a));

Prints "012.345,6"

ChrisCantrell
  • 3,833
  • 1
  • 22
  • 14
0

You can use the DecimalFormatSymbols class to set the grouping and decimal separator to any character you want. An example is shown in the Java tutorials (in the Altering the Formatting Symbols section): http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html

In the pattern itself grouping is always denoted by a , and the decimal point by a ..

yiannis
  • 1,421
  • 12
  • 21
0

According to my reading of the javadoc, DecimalFormat only supports "grouping" in the integer part of a number; i.e. the part before the decimal place.

  • This is implied by the syntax of the format string in which ',' is only allowed before the '.'.

  • It is also implied by the javadoc for setGroupingSize(int) which says

    "Grouping size is the number of digits between grouping separators in the integer portion of a number".

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216