JDK-4510618 : [Fmt-Nu] French thousands separator is non-breaking space
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 1.3.0,5.0u4,6u10
  • Priority: P4
  • Status: Resolved
  • Resolution: Won't Fix
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2001-10-04
  • Updated: 2018-01-05
  • Resolved: 2018-01-05
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  

Name: yyT116575			Date: 10/03/2001

Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

This is an attempt to reopen bug 4350931.
That bug complained that the French thousands separator 
(when formatting numbers) does not print.  The bug was 
closed; it was claimed that the thousands separator is a space.

It is true that the separator is a space, but it is a special non-breaking 
space -- the character 0xA0.  This means that if the user in a UI types
a number with (normal) spaces, the Java formatting code will reject it 
with an error.

It's not even clear that this special space character will be displayed 
as such in a HTML client.  Certainly it will not occur to a user who 
sees an existing value that he needs to type a funny space character.

The following source code shown the spaces will cause the number
be rejected.

import java.text.*;
import java.util.Locale;

public class French {
  public static void main(String args []) {
    NumberFormat form = NumberFormat.getInstance(Locale.FRENCH);
    String fmt = form.format(123456.789);

    System.out.println("Here is the formatted value:");
    for (int i = 0; i < fmt.length(); i++) {
      System.out.print((int) (fmt.charAt(i)));
      System.out.println(" " + fmt.charAt(i));

    String fmtAsSpace = "123 456,789";
    System.out.println("About to parse " + fmtAsSpace);

    try {
    } catch (Exception e) {

Here is the output:

Here is the formatted value:
49 1
50 2
51 3
160 ?
52 4
53 5
54 6
44 ,
55 7
56 8
57 9
About to parse 123 456,789
Cannot format given Object as a Number
(Review ID: 132812) 

Closing it as won't fix, as the grouping separator for the French locale to be used should be \u00a0 (non-breaking space) not \u0020 (space) and parsing does the strict checking of the input string. Workaround given can be used to obtain the desired behavior.

WORK AROUND (1) Remove user's grouping separator (i.e. U+0020) in a String to be parsed. DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.FRENCH); char groupingSeparator = dfs.getGroupingSeparator(); if (groupingSeparator == '\u00a0') { fmtAsSpace = fmtAsSpace.replace(" ", ""); } (2) Replace user's grouping separator with the formatter's grouping seperator (U+00A0) if it's inconvenient to remove all spaces. DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.FRENCH); char groupingSeparator = dfs.getGroupingSeparator(); if (groupingSeparator == '\u00a0') { fmtAsSpace = fmtAsSpace.replaceAll(" (\\d)", groupingSeparator + "$1"); // or " (\\d\\d\\d)" } Please note that there's no way to get a DecimalFormatSymbols from a NumberFormat. This example assumes that the default DecimalFormatSymbols is used in the NumberFormat implementation.

EVALUATION I don't think there's any realistic way to fix this problem without breaking compatibility. The easiest workaround would be to remove all space characters in the string to be parsed. Please refer to Work Around. Please note that parse() doesn't require use of the grouping separator even setGroupingUsed(true) is called.

EVALUATION I guess what's really meant here is parsing - i.e., the line System.out.println(form.format(fmtAsSpace)); should be System.out.println(form.parse(fmtAsSpace)); With that, fmtAsSpace is parsed as 123, i.e., characters starting with the space are simply ignored. This stems from the fact that parsing is designed to be able to extract pieces of formatted data from a text stream - e.g., the first part might just be the day component of a date string. Obviously, that's not what an application is looking for when it calls parse(String). It seems what the submitter is really requesting is a way to parse the entire string regardless of whether it uses regular or nonbreaking spaces. ###@###.### 2001-10-03