2009-08-21 9 views
10

Realmente me estoy rascando la cabeza en este caso. He estado usando SimpleDateFormat s sin problemas durante un tiempo, pero ahora, usar un SimpleDateFormat para analizar las fechas es (solo algunas veces) simplemente incorrecto.Análisis de fecha incoherente usando SimpleDateFormat

Específicamente:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
Date date = sdf.parse("2009-08-19 12:00:00"); 
System.out.print(date.toString()); 

imprime la cadena Wed Aug 19 00:00:00 EDT 2009. ¿Qué diablos? - ¡Ni siquiera analiza la fecha equivocada todo el tiempo!


Actualización: Eso lo arregló muy bien. ¿No lo sabrías? Eso también se usó mal en algunos otros lugares. Tengo que adorar la depuración del código de otras personas :)

+3

Desearía que la gente dejara de llamar a las cosas "extrañas" y "extrañas" siempre que cometan errores. :/ – Bombe

+0

Lo siento. Estaba depurando el código que alguien muchos años más tarde mi senior había escrito, y esperaba poder confiar. –

Respuesta

25

Creo que desea utilizar el formato HH, en lugar de 'HH' de modo que está utilizando horas entre 00-23. 'hh' toma el formato en incrementos de 12 horas, y asume que está en AM.

Así que este

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
Date date = sdf.parse("2009-08-19 12:00:00"); 
System.out.print(date.toString()); 

debe imprimir

Wed Aug 19 de 12:00:00 EDT 2009

2

Está imprimiendo la representación toString() de la fecha, en lugar de la representación del formato. Es posible que también desee verificar la representación de la hora. H y h significan algo diferente. H es para el reloj de 24 horas (0-23), h es para el reloj de 12 horas (1-12), (también hay k y K para 1-24 y 0-11 horas base respectivamente)

Usted que tenga que hacer algo como:

//in reality obtain the date from elsewhere, e.g. new Date() 
Date date = sdf.parse("2009-08-19 12:00:00"); 

//this format uses 12 hours for time 
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
//this format uses 24 hours for time 
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

System.out.print(sdf.format(date)); 
System.out.print(sdf2.format(date)); 
+0

Lo intentaré, pero no creo que vaya a resolver el problema. En mi aplicación, en realidad no estoy convirtiendo nuevamente a una cadena. Estoy guardando la Fecha en una base de datos, y allí también está mal. –

+0

¿Son consistentes sus cadenas de formato? Algunos SGBD convertirán valores automáticamente si pueden resolver las cosas, otros no. ¿Los valores problemáticos en una columna (s) con diferente formato aplicados en el nivel db? ¿O proviene de una conexión que tiene diferentes parámetros establecidos? – DaveE

1

tl; dr

LocalDateTime ldt = LocalDateTime.parse("2009-08-19 12:00:00".replace(" " , "T")); 

java.time

Otras respuestas son correctas pero el uso de legado clases de fecha y hora. Esas viejas clases molestas han sido suplantadas por las clases java.time.

Su cadena de entrada está cerca del formato estándar ISO 8601. Modifique reemplazando el espacio en el medio con un T. Luego se puede analizar sin especificar un patrón de formateo. Las clases java.time usan ISO 8601 de forma predeterminada al analizar/generar cadenas.

String input = "2009-08-19 12:00:00".replace(" " , "T"); 

Los datos de entrada no tienen información sobre offset-from-UTC o la zona horaria. Entonces analizamos como LocalDateTime.

LocalDateTime ldt = LocalDateTime.parse(input); 

Si por el contexto conoce el desplazamiento previsto, aplíquelo. Tal vez fue pensado para UTC (un desplazamiento de cero), donde podemos usar la constante ZoneOffset.UTC.

OffsetDateTime odt = ldt.atOffset(ZoneOffset.UTC); 

O tal vez sepa que fue diseñado para un huso horario en particular. Un huso horario es un desplazamiento más un conjunto de reglas para manejar anomalías como el horario de verano (DST).

ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/Montreal")); 

Sobre java.time

El marco java.time está incorporado en Java 8 y versiones posteriores. Estas clases suplantan a las antiguas clases problemáticas de fecha y hora como java.util.Date, .Calendar, & java.text.SimpleDateFormat. El proyecto Joda-Time, ahora en maintenance mode, recomienda la migración a java.time.

Para obtener más información, consulte el Oracle Tutorial. Y busque Stack Overflow para obtener muchos ejemplos y explicaciones.

Gran parte de la funcionalidad java.time está de vuelta-portado a Java 6 & 7 en ThreeTen-Backport y adaptado además para Android en ThreeTenABP (ver How to use…).

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time.

Cuestiones relacionadas