DecimalFormat subpattern boundary not working right
Asked Answered
P

2

5

I am using DecimalFormat to create a formated decimal that is always 6 characters long. At first I used the format string of new DecimalFormat("000.00") but this gave me a bug for negative numbers. The minus sign is added and makes the number one space larger resulting in -005.25 and not -05.25 as desired.

I have been able to fix this with the following code

DecimalFormat fmt;  
if(netAmt < 0){  
    fmt = new DecimalFormat("00.00");  
}else{  
    fmt = new DecimalFormat("000.00");  
}  

System.out.println(fmt.format(netAmt));

But DecimalFormat has the ; character to format negative numbers differently then positive numbers. I have not been able to get this work correctly. As I understand it the following code should work just like the above.

DecimalFormat fmt = new DecimalFormat("000.00;00.00");  

System.out.println(fmt.format(netAmt));

The result is that the pattern before the ; is used for both negative and positive numbers causing the -005.25 error to remain. What am I doing wrong? Am I misunderstanding what ; is for?

Posen answered 17/2, 2011 at 16:3 Comment(0)
S
4

Does the following string pattern help you: "%06.2f%n" A fixed width of 6 with "0" padding the front?

example

System.out.println(String.format("%06.2f%n",1.3));
System.out.println(String.format("%06.2f%n",-3.323));

What do you want the behavior to be when the number is greater than 3 digits, ie won't fit?

Striated answered 5/4, 2011 at 10:14 Comment(1)
Wow that works perfectly. Based on this and what Rulmeq dug up it looks like DecimalFormat is not the best at all kinds of number formatting. I'll have to keep that in mind. Thanks! Snipping the strings first few chars is preferred but I can always check the string again for good measure.Posen
S
5

I'm pretty sure that the second pattern is ignored, and only the parts specific to the negation are used, e.g. the - sign or () etc.

That's my understanding of reading the following passage from the JavaDocs

A DecimalFormat pattern contains a positive and negative subpattern, for example, "#,##0.00;(#,##0.00)". Each subpattern has a prefix, numeric part, and suffix. The negative subpattern is optional; if absent, then the positive subpattern prefixed with the localized minus sign ('-' in most locales) is used as the negative subpattern. That is, "0.00" alone is equivalent to "0.00;-0.00". If there is an explicit negative subpattern, it serves only to specify the negative prefix and suffix; the number of digits, minimal digits, and other characteristics are all the same as the positive pattern. That means that "#,##0.0#;(#)" produces precisely the same behavior as "#,##0.0#;(#,##0.0#)".

Sampling answered 17/2, 2011 at 16:16 Comment(3)
I just tested this and it's working as you have said. I'll end up using the code I had then. It's a shame that it works like that, It's confusing and limited.Posen
I'll note something weird I noticed when testing this. If the pattern after the ; is not the same length as the first pattern the suffix (but not the prefix) is lost. For example 000.00;(-+-000.00) and 000.00;(-+-00Y.00) result in (-+-005.25) but 000.00;(-+-0000.00) and 000.00;(-+-00.00) result in (-+-005.25Posen
The next paragraph in that link contains the following "care must be taken that the symbols and strings do not conflict, or parsing will be unreliable" - So I presume it's falling over on parsing the pattern.Sampling
S
4

Does the following string pattern help you: "%06.2f%n" A fixed width of 6 with "0" padding the front?

example

System.out.println(String.format("%06.2f%n",1.3));
System.out.println(String.format("%06.2f%n",-3.323));

What do you want the behavior to be when the number is greater than 3 digits, ie won't fit?

Striated answered 5/4, 2011 at 10:14 Comment(1)
Wow that works perfectly. Based on this and what Rulmeq dug up it looks like DecimalFormat is not the best at all kinds of number formatting. I'll have to keep that in mind. Thanks! Snipping the strings first few chars is preferred but I can always check the string again for good measure.Posen

© 2022 - 2024 — McMap. All rights reserved.