SimpleDateFormat produce una fecha de hora incorrecta al analizar “YYYY-MM-dd HH: mm”

Estoy tratando de analizar una String ( YYYY-MM-dd HH:mm ) hasta la Date , pero obteniendo una fecha incorrecta de la esperada.

CÓDIGO:

 Date newDate = null; String dateTime = "2013-03-18 08:30"; SimpleDateFormat df = new SimpleDateFormat("YYYY-MM-dd HH:mm", Locale.ENGLISH); df.setLenient(false); try { newDate = df.parse(dateTime); } catch (ParseException e) { throw new InvalidInputException("Invalid date input."); } 

Produce:

Dom 30 dic 08:30:00 EST 2012 (incorrecto)

Traté de quitar a Lenient, pero no tuve suerte.

Actualizar

Gracias a Sudhanshu por la respuesta, me ayudó a resolver la conversión de Java. Cuando ingreso la fecha de regreso desde el código anterior a la base de datos obtengo la fecha correctamente, pero la hora siempre es 00:00 .

 ps.setDate(3, new java.sql.Date(app.getDate().getTime())); 

YYYY debería ser aaaa-

 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH); 

Por favor, consulte la documentación de SimpleDateFormat aquí
Java 6: http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
Java 7: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

Use la caja pequeña Y, no las tapas. es decir, aaaa no aaaa

Verifique los comentarios aquí: Formato de fecha simple de Java y otras respuestas a las que se hace referencia allí.

Hay dos problemas.

  1. La cadena de formato debe ser "yyyy-MM-dd HH:mm" .
  2. El tipo de datos para almacenar la hora es TimeStamp y no Date en la base de datos.

Corrija ambas cosas y podrá almacenar y recuperar la Fecha con el tiempo.

Aquí está la respuesta moderna. Las otras respuestas fueron buenas respuestas cuando se escribieron en 2013. El año posterior apareció la API de fecha y hora moderna como reemplazo de las antiguas clases Date , SimpleDateFormat y amigos. En mi humilde opinión, debería usar las nuevas clases ahora. Son mucho más amigables con los progtwigdores.

  LocalDateTime newDate = null; String dateTime = "2013-03-18 08:30"; DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm", Locale.ENGLISH); try { newDate = LocalDateTime.parse(dateTime, dtf); } catch (DateTimeParseException e) { throw new InvalidInputException("Invalid date input."); } 

Excepto por los nombres de clase, no es tan diferente del código anterior. Con otros ejemplos, habrá diferencias, por lo general, las clases modernas proporcionarán un código más claro y menos oportunidades de errores.

Para solo una pequeña demostración de una diferencia, intentemos con la cadena de patrón de formato que tenía con YYYY en mayúscula:

  DateTimeFormatter dtf = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm", Locale.ENGLISH); 

Ahora el código arroja un java.time.format.DateTimeParseException: Text '2013-03-18 08:30' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MonthOfYear=3, DayOfMonth=18, WeekBasedYear[WeekFields[SUNDAY,1]]=2013},ISO resolved to 08:30 of type java.time.format.Parsed . Es largo, lo sé. Lo que hay que destacar es que no hay un año entre los campos que menciona, solo un WeekBasedYear. No es lo mismo; y es posible que ya se haya dado cuenta de que esto es exactamente porque Y mayúscula es para el año de una semana (solo útil con un número de semana), donde debe usar minúscula y para el año. Considero que este comportamiento es un poco más útil que lo que hicieron las clases anteriores: te dieron un resultado que estaba mal, fingieron que todo estaba bien y te dejaron completamente a oscuras sobre lo que estaba mal.

Luego entiendo que desea almacenar su fecha y hora en una base de datos. En los viejos tiempos, se convertía a algún tipo apropiado de java.sql . Ya no es necesario. Creo que con un controlador JDBC 4.2 puedes hacer:

  ps.setObject(3, newDate); 

Sin embargo, no he probado esto con una base de datos. Tenga en cuenta que utiliza setObject() lugar de setDate() .