## Formatear con Patrones

Se puede utilizar la clase DecimalFormat para formatear números decimales en cadenas específicas de la Localidad. Esta clase permite controlar los ceros iniciales y finales, los sufijos y prefijos, separadores (millares), y el separador decimal. Si se quiere cambiar un símbolo del formateo como el saperador decimal, se puede utilizar DecimalFormatSymbols en conjunción con la clase DecimalFormat. Estas clases ofrecen una gran flexibilidad en el formateo de números, pero hacen el código más complejo. Siempre que sea posible, se debería utilizar la clase NumberFormat, que se describió en la sección anterior, en vez de DecimalFormat y DecimalFormatSymbols.

Utilizando ejemplos, las siguientes líneas mostrarán como utilizar las clases DecimalFormat y DecimalFormatSymbols. Los fragmentos de código se han extraido de un programa llamado DecimalFormatDemo.java.

#### Construir Patrones

Las propiedades de formateo de DecimalFormat se específican con un String patrón. El patrón determina la apariencia del número formateado. Para una descripción completa de la síntaxis de los patrones puedes ver la página Síntaxis de los Patrones de Formateo de Números.

En el siguiente ejemplo, hemos creado un formateador, pasándole un patrón al constructor de DecimalFormat. Luego, le hemos pasado un valor double al método format, que devuelve un String formateado:

    DecimalFormat myFormatter = new DecimalFormat(pattern);
    String output = myFormatter.format(value);
    System.out.println(value + "  " + pattern + "  " + output);

La salida de las líneas de código precedentes se describe en la siguiente tabla. El valor es el número, un double, que será formateado. El Patrón es el String que específica las propiedades de formateo. La Salida, que es un String, representa el número formateado:

Valor | Patrón | Salida | Explicación
--- | --- | --- | ---
123456.789 | ###,###.### | 123,456.789 | El signo Almohadilla (#) indica un dígito, la coma la posición del separador de millares y el punto la posición del separador decimal.
123456.789 | ###.## | 123456.79 | El valor tiene tres dígitos a la derecha del punto decimal, pero el patrón sólo tiene dos. El método format maneja esto redondeando.
123.78 | 000000.000 | 000123.780 | El patrón específica relleno con ceros, porque se utiliza el caracter Cero en vez de la almohadilla (#).
12345.67 | $###,###.### | $12,345.67 | El primer carácter del patrón es el signo del dólar ($). Observa que este signo precede inmediatamente al dígito más a la izquierda de la salida formateada.
12345.67 | \u00a5###,###.### | ¥12,345.67 | El patrón específica el signo del Yen Japonés (¥) con su valor Unicode \u00a5.

#### Formateo Sensible a la Localidad

El ejemplo anterior creaba un objeto DecimalFormat para la Localidad por defecto. Si se quiere un objeto DecimalFormat para una localidad distinta, se ejemplariza un NumberFormat y luego se fuerza a DecimalFormat. Entonces, el objeto DecimalFormat formetará los patrones definidos de una forma sensible a la localidad. Aquí se puede ver un ejemplo:

    NumberFormat nf = NumberFormat.getNumberInstance(loc);
    DecimalFormat df = (DecimalFormat)nf;
    df.applyPattern(pattern);
    String output = df.format(value);
    System.out.println(pattern + "  " + output + "  " + loc.toString());

Abajo podemos ver el resultado de la ejecución de este código. Los números formateados, en la segunda columna, varían con la Localidad:

    ###,###.###  123,456.789  en_US
    ###,###.###  123.456,789  de_DE
    ###,###.###  123 456,789  fr_FR

Por eso, los patrones de formateo que hemos utilizado hasta ahora seguían las convenciones del Inglés Norteamericano. Por ejemplo, en el patrón "###,###.##" la coma es el separador de millares y el punto representa el punto decimal. Esta convención está bien, sabiendo que los usuarios finales no están expuestos a ellas. Sin embargo, algunas aplicaciones, como las hojas de cálculo y los generadores de informes, permiten al usuario final definir sus propios patrones de formateo. Para esas aplicaciones, los patrones de formateo especificados por el usuario final deberían utilizar la notación localizada. En estos casos querremos llamar al método applyLocalizedPattern sobre el objeto DecimalFormat.

#### Modificar los Símbolos de Formateo

Con la clase DecimalFormatSymbols se pueden modificar los símbolos que aparecen en los números formateados porducidos por el método format. Estos símbolos incluyen el punto decimal, el separador de millares, el signo menos, y el signo de porcentaje además de algunos más.

En el siguiente ejemplo podemos ver el uso de DecimalFormatSymbols aplicando un formato inusual a un número. Empezamos ejemplarizando DecimalFormatSymbols sin argumentos, lo que devuelve un objeto para la Localidad por defecto, (Como DecimalFormatSymbols es una clase sensible a la Localidad, podríamos haber específicado una Localidad cuando llamamos al constructor.) Luego, modificamos el separador decimal y el de millares. Luego específicamos el DecimalFormatSymbols cuando ejemplarizamos la clase DecimalFormat. Sólo para hacer las cosas más complicadas, cambiamos la numero de agrupamiento del formateador de tres a cuatro. Finalmente llamamos al método format.

Aquí tienes el código de Ejemplo:

    DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols();
    unusualSymbols.setDecimalSeparator('|');
    unusualSymbols.setGroupingSeparator('^');

    String strange = "#,##0.###";
    DecimalFormat weirdFormatter = new DecimalFormat(strange, unusualSymbols);
    weirdFormatter.setGroupingSize(4);

    String bizarre = weirdFormatter.format(12345.678);
    System.out.println(bizarre);

Esto es lo que aparecerá cuando imprimamos este extraño número formateado

    1^2345|678

Ozito