Internacionalización de Programas Java

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.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP