|
Internacionalización de Programas Java |
Formateo de Fechas y Horas
Los objetos Date representan fechas y horas. No se puede mostrar o imprimir un objeto Date sin convertirlo primero a un String que esté en el formato apropiado. Pero, ¿Cuál es el formato adecuado? Primero, el formato debería estar conforme a las convenciones de la Localidad del usuario final. Por ejemplo, los alemanes reconocerán esto 9.4.98 como una fecha válida, pero los norteamericanos esperarán que la misma fecha aparezca como 4/9/98. Segundo, el formato debería incluir la información necesaria. Por ejemplo, un progama que mida el rendimiento de una red podría mostrar milisegundos. Probablemente un calendario de citas on-line no mostrará milisegundos, pero si que mostrará los días de la semana.
Esta lección explica como formatear fechas y horas en diferentes formas, y de una manera sensible a la Localidad. Si sigues las técnicas descritas en esta lección, tus programas no sólo mostrarán las fechas y horas en la Localidad apropiada, sino que el código fuente permanecera independiente de cualquier Localidad específicada.
Utilizar Formato Predefinidos
La clase DateFormat proporciona estilos de formateo predefinidos que son específicos de la Localidad y fáciles de utiliar.
La clase DateFormat permite formatear fechas y horas con estilos predefinidos de una forma sensible a la Localidad, DateFormat no soporta todas las posibles definiciones de Localidades. Para ver las definiciones de Locale que reconoce DateFormat, llamamos al método getAvailableLocales.
Locale[] locales = DateFormat.getAvailableLocales();
En las siguientes secciones, veremos cómo formatear fechas y horas con la clase DateFormat. Los ejemplos se han sacado el programa DateFormatDemo.java.
Fechas
Formatear fechas con la clase DateFormat es un proceso en dos pasos. Primero se crea un formateador con el método getDateInstance. Segundo, se llama al método format, que devuelve un String que contiene la fecha formateada. En el siguiente ejemplo, hemos formateado la fecha de hoy llamando a estos dos métodos.
Date today; String dateOut; DateFormat dateFormatter; dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, currentLocale); today = new Date(); dateOut = dateFormatter.format(today); System.out.println(dateOut + " " + currentLocale.toString());
Aquí está la salida generada por este código. Observa que los formatos de fechas varían con la Localidad. Como DateFormat es sensible a la Localidad, tiene cuidado de los detalles de formateo para cada Localidad.
9 avr 98 fr_FR 9.4.1998 de_DE 09-Apr-98 en_US
En el ejemplo de código anterior, hemos específicado el estilo de formato DEFAULT. Este estilo es sólo uno de los estilos de formato predefinidos que proporciona la clase DateFormat.
- DEFAULT
- SHORT
- MEDIUM
- LONG
- FULL
La siguiente tabla muestra cómo se formatea cada estilo para las Localidades de U.S. y Francia.
| Estilo | Localidad U.S. | Localidad Francia |
|---|---|---|
| DEFAULT | 10-Apr-98 | 10 avr 98 |
| SHORT | 4/10/98 | 10/04/98 |
| MEDIUM | 10-Apr-98 | 10 avr 98 |
| LONG | April 10, 1998 | 10 avril 1998 |
| FULL | Friday, April 10, 1998 | vendredi, 10 avril 1998 |
Horas
Los objetos Date representan tanto fechas como horas. Formatear horas con la clase DateFormat es similar al formateo de fechas, excepto en que el formateador se crea con el método getTimeInstance.
DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, currentLocale);
La siguiente tabla muestra los estilos de formatos predefinidos para las horas en las localidades de U.S. y Alemania.
| Estilo | Localidad U.S. | Localidad Alemania |
|---|---|---|
| DEFAULT | 3:58:45 PM | 15:58:45 |
| SHORT | 3:58 PM | 15:58 |
| MEDIUM | 3:58:45 PM | 15:58:45 |
| LONG | 3:58:45 PM PDT | 15:58:45 GMT+02:00 |
| FULL | 3:58:45 oclock PM PDT | 15.58 Uhr GMT+02:00 |
Fechas y Horas
Para mostrar la fecha y la hora en la misma String, se crea el formateador con el método getDateTimeInstance. El primer parámetro es el estilo de fecha y el segundo es el estilo de la hora. El tercer parámetro es nuestro viejo amigo Locale. Aquí tienes un ejemplo rápido.
DateFormat formatter;
formatter = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.LONG,
currentLocale);
Para la localidad de U.S., el formateado de este ejemplo, formateará la fecha y la hora de esta forma.
April 10, 1998 4:05:54 PM PDT
Si el ejemplo del formateador se hubiera creado con la Localidad Francia, el String devuelto por el método format sería.
11 avril 1998 01:05:54 GMT+02:00
Formatear con Patrones
Con la clase SimpleDateFormat, se pueden crear formatos personalizados específicos de la Localidad.
En la sección anterior, Utilizar formatos predefinidos, describimos los estilos de formatos proporcionados por la clase DateFormat. En la mayoría de los casos, estos formatos predefinidos son suficiente. Sin embargo, si se quieren crear formatos personalizados, se debe utilizar la clase SimpleDateFormat.
En la siguientes líneas, proporcionaremos varios ejemplos de código que demuestran el uso de los métodos de la clase SimpleDateFormat. Podrás encontrar el código completo en el fichero llamado SimpleDateFormatDemo.java.
Sobre los Patrones
Cuando se crea un objeto SimpleDateFormat, se específica un patrón en un String. Los contenidos de este patrón determinan el formato de la fecha y de la hora. Para una descripción completa sobre la síntaxis de los patrones puedes ver las tablas de la sección Síntaxis de los Patrones de Formato de Fechas. Podremos ver algunos ejemplos de patrones en los siguientes ejemplos.
En el siguiente código hemos específicado el patrón cuando se crea el objeto SimpleDateFormat y luego llamamos al método format. El String devuelto por el método format contiene la fecha y hora formateadas y está lista para mostrarse.
Date today; String output; SimpleDateFormat formatter; formatter = new SimpleDateFormat(pattern, currentLocale); today = new Date(); output = formatter.format(today); System.out.println(pattern + " " + output);
La tabla siguiente muestra la salida generada por el código anterior cuando se especifica la localidad de U.S..
| patrón | Salida |
|---|---|
| dd.MM.yy | 09.04.98 |
| yyyy.MM.dd G 'at' hh:mm:ss z | 1998.04.09 AD at 06:15:55 PDT |
| EEE, MMM d, ''yy | Thu, Apr 9, '98 |
| h:mm a | 6:15 PM |
| H:mm | 18:15 |
| H:mm:ss:SSS | 18:15:55:624 |
| K:mm a,z | 6:15 PM,PDT |
| yyyy.MMMMM.dd GGG hh:mm aaa | 1998.April.09 AD 06:15 PM |
Patrones y Localidades
La clase SimpleDateFormat es sensible a la localidad. Si se ejemplariza SimpleDateFormat sin un parámetro Locale, formateará la fecha y hora de acuerdo a la Localidad por defecto. Tanto el patrón como la Localidad determinan el formato. Para el mismo patrón, la clase SimpleDateFormat podría formatear la fecha y la hora de forma diferente si varía la Localidad.
En el siguiente ejemplo, el patrón está codificado en la sentencia que crea el objeto SimpleDateFormat.
Date today;
String result;
SimpleDateFormat formatter;
formatter = new SimpleDateFormat("EEE d MMM yy", currentLocale);
today = new Date();
result = formatter.format(today);
System.out.println("Locale: " + currentLocale.toString());
System.out.println("Result: " + result);
El código anterior genera esta salida. Aunque el patrón esté codificado,el formato de la fecha cambia cada vez que se especifica una Localidad diferente.
Locale: fr_FR Result: ven 10 avr 98 Locale: de_DE Result: Fr 10 Apr 98 Locale: en_US Result: Thu 9 Apr 98
Cambiar los Símbolos de Formateo
Utilizando la clase DateFormatSymbols, se pueden cambiar los símbolos que representan los nombres de los meses, de los días de la semana, y otros elementos de formateo.
El método format de SimpleDateFormat devuelve un String formado por dígitos y símbolos. Por ejemplo, en el String "Friday, April 10, 1998," los símbolos son "Friday" y "April." Si los símbolos encapsulados en SimpleDateFormat no cubren tus necesidades, puedes cambiarlos con la clase DateFormatSymbols. Se pueden cambiar los símbolos que representan los nombres de los meses, de los días de las semana, de las zonas horarias. etc.
Echemos un vistazo a un ejemplo que modifica los nombres cortos de los días de la semana. Podrás encontrar el código fuente de este ejemplo en el fichero llamado DateFormatSymbolsDemo.java. En este ejemplo, empezamos creando un objeto DateFormatSymbol para la Localidad de U.S. Tenemos curiosidad sobre las abreviaturas que encapsula DateFormatSymbol para los días de la semana, por eso llamamos al método getShortWeekdays. Hemos decidido crear versiones en mayúsculas de estas abreviaturas en el array de String llamado capitalDays. Luego aplicamos el nuevo conjunto de símbolos de captitalDays al objeto DateFormatSymbol con el método setShortWeekdays. Finalmente , ejemplarizamos la clase SimpleDateFormat, específicando el DateFormatSymbol que tenía los nuevos nombres. Aquí está el código fuente.
Date today;
String result;
SimpleDateFormat formatter;
DateFormatSymbols symbols;
String[] defaultDays;
String[] modifiedDays;
symbols = new DateFormatSymbols(new Locale("en","US"));
defaultDays = symbols.getShortWeekdays();
for (int i = 0; i < defaultDays.length; i++) {
System.out.print(defaultDays[i] + " ");
}
System.out.println();
String[] capitalDays = {
"", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
symbols.setShortWeekdays(capitalDays);
modifiedDays = symbols.getShortWeekdays();
for (int i = 0; i < modifiedDays.length; i++) {
System.out.print(modifiedDays[i] + " ");
}
System.out.println();
System.out.println();
formatter = new SimpleDateFormat("E", symbols);
today = new Date();
result = formatter.format(today);
System.out.println(result);
La salida generada por este código se muestra abajo. La primera línea contiene los nombres cortos de los días de la semana antes de cambiarlos. La segunda línea contiene los nombres en mayúsculas que hemos aplicado con el método setShortWeekdays. Estas dos primeras líneas parecen identadas, porque la primera cadena del array de nombres es null. La última línea muestra el resultado devuelto por el método SimpleDateFormat.format.
Sun Mon Tue Wed Thu Fri Sat SUN MON TUE WED THU FRI SAT WED
Síntaxis de los Patrones de Fechas
Se puede diseñar un patrón de formato personalizado para fechas y horas con la lista de símbolos de la siguiente tabla:
| Símbolo | Significado | Presentación | Ejemplo |
|---|---|---|---|
| G | designador de era | Texto | AD |
| y | año | Número | 1996 |
| M | mes del año | Texto y Número | Julio y 07 |
| d | día del mes | Número | 10 |
| h | hora en am/pm (1-12) | Número | 12 |
| H | hora del día (0-23) | Número | 0 |
| m | minuto | Número | 30 |
| s | segundo | Número | 55 |
| S | milisegundo | Número | 978 |
| E | día de la Semana | Texto | Jueves |
| D | día del año | Número | 189 |
| F | día de la semana en el mes | Número | 2 (2nd Wed in July) |
| w | Semana del año | Número | 27 |
| W | Semana en el mes | Número | 2 |
| a | Marcador am/pm | Texto | PM |
| k | hora del día(1-24) | Número | 24 |
| K | hora en am/pm (0-11) | Número | 0 |
| z | Zona horaria | Texto | Pacific Standard Time |
| ' | escape para texto | Delimitador | (none) |
| ' | Comilla simple | Literal | ' |
Los caracteres que no son letras se tratan como texto entrecomillado. Esto es, apareceran en el texto formateado aunque no esten encerrados entre comillas.
El número de símbolos y letras específicadas también determina el formato. Por ejemplo, si el patrón "zz" resulta "PDT," el patrón "zzzz" generará "Pacific Daylight Time." La siguiente tabla sumariza estas reglas:
| Presentación | Números o símbolos | Resultado |
|---|---|---|
| Texto | 1 - 3 | forma abreviada, si existe |
| Texto | >= 4 | forma completa |
| Número | Se requiere el menor número de dígitos | Los números cortos se rellenan con ceros (para un año, si el número de 'y' es 2, el año se truncará a 2 dígitos) |
| Texto y Número | 1 - 2 | forma de texto |
| Texto y Número | 3 | forma numérica |
















































