Analisando o formato de data ISO 8601 como 2015-06-27T13: 16: 37.363Z em Java

Eu estou tentando analisar uma String usando SimpleDateFormat .

Este é o meu código atual:

 public String getCreatedDateTime() { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-ddEHH:mm:ss.zzzz"); try { Date date = simpleDateFormat.parse("2015-06-27T13:16:37.363Z"); return date.toString(); } catch (ParseException e) { return "Error parsing date"; } } 

Como você pode ver, basta colocar uma constante no método parse () para fins de teste.

Então, é isso que estou tentando analisar:

2015-06-27T13: 16: 37,363Z

Este é o padrão SimpleDateFormat que estou usando:

aaaa-MM-ddEHH: mm: ss.zzzz

Eu continuo recebendo o ParseException.

Eu sei que é proably por causa do .zzzz no final, mas eu não tenho idéia do que .363Z pode representar, então eu usei apenas algumas letras aleatórias. Péssima ideia.

Eu aprecio muito sua ajuda. Obrigado!

Tente com esse padrão (observe o X no final e o ‘T’ no meio):

 "yyyy-MM-dd'T'HH:mm:ss.SSSX" 

Da documentação do SimpleDateFormat do Java:

Fuso horário ISO 8601:

Para análise, “Z” é analisado como o designador de fuso horário UTC.

E, da parte em que descreve os diferentes personagens:

X – fuso horário – fuso horário ISO 8601

EDITAR

Se estiver usando o Android, o “X” não é suportado.

Você pode usar este padrão (nota Z é um literal agora):

 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" 

Porém, você obterá a data no fuso horário atual e precisará convertê-la para UTC, se necessário.

tl; dr

Ignore o padrão de formatação. O formato padrão ISO 8601 é usado por padrão.

 Instant.parse( "2015-06-27T13:16:37.363Z" ) 

ISO 8601

Seu formato de string é formalmente definido pelo padrão ISO 8601 .

Basicamente, sua pergunta é uma duplicata desta, convertendo a string compatível com ISO 8601 para java.util.Date .

Alternativas

A resposta por eugenioy está correta.

Mas você deve saber que as classs java.util.Date/.Calendar/java.text.SimpleDateFormat antigas associadas ao Java são notoriamente problemáticas e devem ser evitadas.

Classes fora de moda

Essas classs antigas agora estão fora de moda, primeiro pela biblioteca Joda-Time de terceiros, e agora pelo novo pacote java.time ( Tutorial ) embutido no Java 8 e posterior (inspirado pelo Joda-Time, definido pela JSR 310 , estendido por o projeto ThreeTen-Extra ).

Tanto o java.time quanto o Joda-Time usam o padrão ISO 8601 como seus padrões ao analisar / gerar representações de string de valores de data e hora. Portanto, o código é simples, não há necessidade de objects formatados personalizados. Não há necessidade de todos os formatos que causaram sua Exceção.

Fuso horário

Tanto o java.time quanto o Joda-Time têm uma class de data e hora zoneada que entende seu fuso horário atribuído (ao contrário de java.util.Date). Se você não atribuir um, o fuso horário padrão atual da JVM será designado.

Tenha em atenção que o fuso horário predefinido da JVM pode ser alterado a qualquer momento . Ele pode mudar na implementação, padronizando para qualquer configuração do SO host. E isso pode mudar a qualquer momento durante o tempo de execução, quando qualquer código em qualquer thread de qualquer aplicativo dentro da JVM chama TimeZone.setDefault . Então é melhor atribuir explicitamente um fuso horário desejado / esperado.

java.time

O Z no final da sua string é curto para Zulu e significa UTC. A class Instant pode analisar diretamente esse formato, para representar um momento na linha do tempo no UTC com uma resolução em nanossegundos.

 String input = "2015-06-27T13:16:37.363Z"; Instant instant = Instant.parse( input ); 

Altere o fuso horário de UTC para algum fuso horário desejado / esperado.

 ZoneID zone = ZoneId.of( "America/Montreal" ) ; ZonedDateTime zdtMontréal = instant.atZone( zone ) ; 

Se você realmente precisa de um java.util.Date para interoperabilidade, converta.

 java.util.Date utilDate = Date.from( zdtMontréal.toInstant() ) ; 

Joda-Time

O projeto Joda-Time está agora no modo de manutenção, com a equipe aconselhando a migration para as classs java.time:

Observe que, a partir do Java SE 8, os usuários são solicitados a migrar para o java.time (JSR-310) – uma parte central do JDK que substitui esse projeto.

Exemplo de código usando o Joda-Time 2.8.1.

 String input = "2015-06-27T13:16:37.363Z" ; DateTimeZone zone = DateTimeZone.UTC ; // Or: DateTimeZone.forID( "America/Montreal" ) ; DateTime dateTime = new DateTime( input, zone ) ; 

Se você realmente precisa de um java.util.Date para interoperabilidade, converta.

 java.util.Date date = dateTime.toDate();