Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8274768

The whitespace separator used by java.text.NumberFormat#format(long) has changed

XMLWordPrintable

    • b21
    • 13
    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Reproduced with on Linux Ubuntu 20.04.3 LTS. Probably OS-agnostic?

      ./java -version
      Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=gasp
      openjdk version "17" 2021-09-14
      OpenJDK Runtime Environment (build 17+35-2724)
      OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)

      To be more precise, I have tracked down this behavior to have changed in Java 13.

      A DESCRIPTION OF THE PROBLEM :
      The whitespace separator used by java.text.NumberFormat#format(long) has changed in Java 17, for the French locale (and maybe for others locales which use whitespace separators).
      In Java 11, this character was: NO-BREAK SPACE (U+00A0)
      In Java 17, this character is: 'NARROW NO-BREAK SPACE' (U+202F)

      We have numerous unit tests which rely on this behavior, and which expect the first character.
      Granted, this separator character was never officially specified by the method documentation. However:
      1) there does not appear to be a rationale for modifying the previous behavior, and we assume the change to be accidental?
      2) from what I can see, the second character requires for the whole String to be internally encoded as UTF-16 (two bytes per character), rather than ISO-8859-1/Latin-1, as possible with the former character. So the new behavior doubles the memory used, for all Strings formatted according to the French locale.

      REGRESSION : Last worked in version 11.0.12

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the test case below

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expect the test case below to succeed, independently from the Java version used
      ACTUAL -
      The test succeeds with Java 11, 12,
      It fails with Java 13, 14, 17, with this puzzling message: org.junit.ComparisonFailure:
      Expected :1 000
      Actual :1 000


      ---------- BEGIN SOURCE ----------
      import java.text.*;
      import java.util.*;

      import org.junit.*;

      /**
       * Succeeds with Java 11, 12,
       * Fails with Java 13, 14, 17
       */
      public final class FrNumberFormatTest
      {
      /**
      * This was the number separator in Java 8, 11 and 12.
      */
      private static final String NBSP = "\u00A0";

      /**
      * This appears to be the number separator in Java 13 to 17.
      * https://en.wikipedia.org/wiki/Template:Narrow_no-break_space
      */
      private static final String NNBSP = "\u202F";

      @Test
      public void checkNumberFormat()
      {
      final String formatted = this.formatFr(1000);
      Assert.assertEquals("1 000", formatted);
      }

      @Test
      public void checkSeparator()
      {
      final String formatted = this.formatFr(1000);
      Assert.assertEquals(NBSP, formatted.substring(1, 2));
      }

      private String formatFr(int number) {
      final NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
      return format.format(number);
      }
      }

      ---------- END SOURCE ----------

      FREQUENCY : always


            naoto Naoto Sato
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: