SimpleDateFormat produzindo data e hora erradas ao analisar “AAAA-MM-dd HH: mm”

Eu estou tentando analisar uma String ( YYYY-MM-dd HH:mm ) para Date , no entanto, recebendo data errada do que o esperado.

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."); } 

Produz:

Dom Dez 30 08:30:00 EST 2012 (errado)

Tentei largar Lenient, mas não tive sorte.

Atualizar

Obrigado Sudhanshu pela resposta, isso me ajudou a resolver a conversão de Java. Quando insiro a data de retorno do código acima no database, estou obtendo a data corretamente, mas a hora é sempre 00:00 .

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

YYYY deveria ser yyyy-

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

Por favor, verifique a documentação para SimpleDateFormat aqui
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 um pequeno estojo Y, não tampas. ou seja yyyy não YYYY

Verifique os comentários aqui: Formato de data simples Java e outras respostas referenciadas lá.

Existem dois problemas.

  1. A string de formato deve ser "yyyy-MM-dd HH:mm" .
  2. O tipo de dados para armazenar a hora é TimeStamp e não Date no database.

Corrija as duas coisas e você poderá armazenar e recuperar Data com o tempo.

Aqui está a resposta moderna. As outras respostas foram boas respostas quando foram escritas em 2013. No ano seguinte, a API moderna de data e hora foi substituída pelas antigas classs Date , SimpleDateFormat e friends. IMHO você deve usar as novas classs agora. Eles são muito mais amigáveis ​​ao programador.

  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."); } 

Exceto pelos nomes das classs, não é diferente do código antigo. Com outros exemplos, haverá diferenças, normalmente as classs modernas fornecerão códigos mais claros e menos oportunidades de erros.

Para apenas uma pequena demonstração de uma diferença, vamos tentar a string de padrão de formato que você tinha com YYYY maiúscula:

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

Agora o código lança um 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 . É longo, eu sei. A coisa a notar é que não há ano entre os campos que menciona, apenas um WeekBasedYear. Não é o mesmo; e você já deve ter percebido que isso é exatamente porque maiúscula Y é para um ano baseado na semana (somente usseful com um número de semana), onde você deve usar y minúsculo para o ano. Eu considero este comportamento um pouco mais útil do que as classs antigas: eles te deram um resultado que estava errado, fingiram que estava tudo bem e deixaram você completamente no escuro sobre o que estava errado.

Em seguida entendo que você deseja armazenar o seu tempo de data para um database. Antigamente, você converteria para algum tipo java.sql apropriado. Não é mais necessário. Eu acredito que com um driver JDBC 4.2 você pode apenas fazer:

  ps.setObject(3, newDate); 

Eu não testei isso com um database, no entanto. Observe que você usa setObject() vez de setDate() .