Los programas almacenan y operan con n�meros de una forma independiente de la Localidad. Antes de mostrar o imprimir un n�mero el programa debe convertirlo a un String que est� en un formato sensible a la Localidad. Por ejemplo, en Francia, el n�mero 123456.78 deber�a ser formateado como 123�456,78, y en Alemania deber�a aparecer como 123.456,78. En esta lecci�n, aprender�s como hacer que tus programas sean idependientes de las convenciones de la localidad para los puntos decimales, los separadores de millares, y otras propiedades de formateo.
�Utilizar Formatos Predefinidos
Utilizando los m�todos de factor�a proporcionados por la clase NumberFormat, se pueden obtener formatos espec�ficos de la localidad para n�meros, monedas y porcentajes.
Llamando a los m�todos de la clase NumberFormat se pueden formatear n�meros, monedas y porcentajes de acuerdo a la Localidad. Sin embargo, hay un error: NumberFormat podr�a no soportar la Localidad especificada. Para conocer las definiciones de Locale soportadas por NumberFormat, llamamos al m�todo getAvailableLocales.
Locale[] locales = NumberFormat.getAvailableLocales();
Si NumberFormat no soporta la localidad que necesitamos, podemos crear nuestro propio formateador. Explicaremos este procedimiento en la siguiente secci�n, Formatear con Patrones.
El siguiente material muestra como obtener formateadores espec�ficos de la localidad para n�meros, monedas y porcentajes. Los c�digos de ejemplo son de un programa llamado NumberFormatDemo.java.
�N�meros
Se pueden utilizar los m�todos de factoria de NumberFormat para formatear n�meros de tipos de datos primitivos, como double, y sus correspondientes objetos, como Double.
En el siguiente fragmento de c�digo, formatearemos un Double de acuerdo a la Localidad. Primero, obtendr�mos un ejemplar de NumberFormat espec�fico de la Localidad, llamando a getNumberInstance. Luego llamamos al m�todo format con el Double como argumento. El m�todo format devuelve el n�mero formateado en un String, que est� listo para ser mostrado.
Double amount = new Double(345987.246); NumberFormat numberFormatter; String amountOut; numberFormatter = NumberFormat.getNumberInstance(currentLocale); amountOut = numberFormatter.format(amount); System.out.println(amountOut + " " + currentLocale.toString());
La salida de este ejemplo muestra como el formato del mismo n�mero var�a con la Localidad.
345 987,246 fr_FR 345.987,246 de_DE 345,987.246 en_US
�Monedas
Si est�s escribiendo apliaciones de negocios, necesitar�s formatear y mostrar valores en monedas. Las monedas se formatean de la misma forma que los n�meros, excepto en que se llama a getCurrencyInstance para crear el formateador. Cuando se llama al m�todo format , devuelve un String que incluye el n�mero formateado y el signo de moneda apropiado.
El siguiente c�digo muestra como formatear moneda de una forma espec�fica de la Localidad.
Double currency = new Double(9876543.21); NumberFormat currencyFormatter; String currencyOut; currencyFormatter = NumberFormat.getCurrencyInstance(currentLocale); currencyOut = currencyFormatter.format(currency); System.out.println(currencyOut + " " + currentLocale.toString());
La salida genera por las l�neas precedentes ser�a esta.
9 876 543,21 F fr_FR 9.876.543,21 DM de_DE $9,876,543.21 en_US
A primera vista, esta salida podr�a parecer err�nea, porque los valores num�ricos son iguales. Por supesto, 9 876 543,21 F no es equivalente a 9.876.543,21 DM. Sin embargo, recuerda que la clase NumberFormat no puede cambiar monedas. Los m�todos pertenecientes a la clase NumberFormat formatean monedas, pero no las convierten.
�Porcentajes
T�mbien se pueden utilizar los m�todos de la clase NumberFormat para formatear porcentajes. Para obtener el formateador espec�fico de la localidad se llama al m�todo getPercentInstance. Con este formateador, un fracci�n como 0.75 se mostrar� como 75%.
El siguiente c�digo muetra como formatear porcentajes.
Double percent = new Double(0.75); NumberFormat percentFormatter; String percentOut; percentFormatter = NumberFormat.getPercentInstance(currentLocale); percentOut = percentFormatter.format(percent);
�Formatear con Patrones
Con la clase DecimalFormat se espec�fica un formato de n�mero con patr�n. La clase DecimalFormatSymbols permite modificar los simbolos de formateo como separadores decimales o el signo negativo.
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 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
�S�ntaxis de los Patrones de Formateo de N�meros
Se pueden dise�ar patrones personalizados para el formateo de n�meros, siguiendo las siguientes reglas espec�ficas por el diagrama BNF.
patr�n := subpatr�n{;subpatr�n} subpatr�n := {prefijo}entero{.fracci�n}{sufijo} prefijo := '\\u0000'..'\\uFFFD' - CaracteresEspeciales sufijo := '\\u0000'..'\\uFFFD' - CaracteresEspeciales entero := '#'* '0'* '0' fracci�n := '0'* '#'*
La notaci�n utilizada en el diagrama anterior se explica en la siguiente tabla.
Notaci�n | Descripci�n |
---|---|
X* | 0 o m�s ejemplares de X |
(X | Y) | X o Y |
X..Y | cualquier caracter de X a Y, inclusives |
S - T | Los caracteres que est�n en S, exceptos los que est�n en T |
{X} | X es opcional |
En el digrama BNF anteiror, el primer subpatr�n especifica el formato para n�meros positivos. El segundo es opcional, espec�fica el el formato para n�meros negativos.
Aunque no est� en el diagrama BNF, puede aparecer una coma dentro de la porci�n "entero".
Dentro de los subpatrones, se espec�fica el formato con s�mbolos especiales. Esto s�mbolos se describen en esta tabla.
S�mbolo | Descripci�n |
---|---|
0 | Un d�gito |
# | Un d�gito, se muestra 0 si no existe |
. | Situaci�n del separador decimal |
, | Situaci�n del separador de millares |
E | Separa el exponente y la mantisa para formatos exponenciales |
; | Separa formatos |
- | Prefijo negativo por defecto |
% | Multiplica por 100 y lo muestra como porcentaje |
? | Multiplica por 1000 y lo muestra como por mil |
� | signo de moneda, reemplazado por un s�mbolo de moneda; Si es doble, reemplazado por el s�mbolo de moneda internacional; si est� presente en el patr�n, se utiliza el separador decimal monetario en vez de el separador decimal. |
X | Se puede utilizar cualquier otro caracter como prefijo o sufijo |
' | utilizado para enmarcar caracteres especiales en prefijos o sufijos. |