2011-09-23 19 views
14
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/New_York")); 
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); 
df.setTimeZone(TimeZone.getTimeZone("America/New_York")); 

try { 
    System.out.println(df.format(cal.getTime())); 
    System.out.println(df.parse(df.format(cal.getTime()))); 
} catch (ParseException e) { 
    e.printStackTrace(); 
} 

Aquí está el resultado:Java DateFormat parse() no respeta la zona horaria

2011-09-24 14:10:51 -0400

Dom Dic 24 de 20:10 : 51 CEST 2011

¿Por qué cuando analizo una fecha que obtengo del formato() no respeta la zona horaria?

Respuesta

23

Está imprimiendo el resultado de llamar a Date.toString(), que siempre usa la zona horaria predeterminada. Básicamente, no debe usar Date.toString() para nada que no sea la depuración.

No olvide que una Date no tienen una zona horaria - representa un instante de tiempo, medido como milisegundos desde la época Unix (medianoche el 1 de enero 1970 GMT).

Si formatea la fecha utilizando su formateador de nuevo, que debería tener la misma respuesta que antes.

Como acotación al margen, yo recomendaría el uso de Joda Time en lugar de Date/Calendar si está haciendo cualquier cantidad significativa de trabajo de fecha/hora en Java; es una API más agradable mucho.

+1

Correcto ... intente imprimir 'System.out.println (df.format (df.parse (df.format (cal.getTime())))); 'y funciona como se esperaba :-) –

+0

Ok, ¿así que aparentemente el problema viene del toString()? Gracias por el consejo. –

+0

@MaximeLaval: De 'Date.toString' en particular, sí, y debe tener en cuenta que una' Fecha' es solo un instante, no en un huso horario o calendario en particular. –

2

DateFormat es una clase abstracta para la fecha/hora de formatear subclases que formatea y analiza las fechas o el tiempo en un de manera independiente del lenguaje. La subclase de formato de fecha/hora, como SimpleDateFormat, , permite el formateo (es decir, fecha -> texto), el análisis (texto -> fecha), y la normalización. La fecha se representa como un objeto Date o como milisegundos desde el 1 de enero de 1970, 00:00:00 GMT.

Desde el spec, devuélvalo tiempo de la época

7

DateFormat.parse() no es una consulta (algo que devuelve un valor y no cambia el estado del sistema). Es un comando que tiene el efecto secundario de actualizar un objeto interno Calendar. Después de llamar al parse(), debe acceder a la zona horaria accediendo a DateFormat's Calendar o llamando al DateFormat.getTimeZone(). A menos que desee descartar la zona horaria original y usar la hora local, no use el valor devuelto Date del parse(). En su lugar, use el objeto de calendario después del análisis. Y lo mismo es cierto para el método de formato. Si va a formatear una fecha, pase el calendario con la información de la zona horaria al objeto DateFormat antes de llamar al format(). Así es como se puede convertir de un formato a otro formato de preservar la zona horaria original:

DateFormat originalDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy"); 
    DateFormat targetDateFormat = new SimpleDateFormat("EEE., MMM. dd, yyyy"); 

    originalDateFormat.parse(origDateString); 
    targetDateFormat.setCalendar(originalDateFormat.getCalendar()); 
    return targetDateFormat.format(targetDateFormat.getCalendar().getTime()); 

Es complicado pero necesario ya parse() no devuelve un valor que conserva zona horaria y format() no acepta un valor que define una zona horaria (la clase Date).

Cuestiones relacionadas