Analizando el formato de fecha ISO 8601 como 2015-06-27T13: 16: 37.363Z en Java

Estoy tratando de analizar una String usando SimpleDateFormat .

Este es mi código actual:

 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 puede ver, simplemente puse una constante en el método parse () para fines de prueba.

Entonces, esto es lo que bash analizar:

2015-06-27T13: 16: 37.363Z

Este es el patrón SimpleDateFormat que estoy usando:

aaaa-MM-ddEHH: mm: ss.zzzz

Sigo recibiendo la ParseException.

Sé que es probable debido a .zzzz al final, pero no tengo idea de qué podría significar .363Z así que acabo de utilizar algunas letras al azar. Mala idea.

Apreciaré mucho tu ayuda. ¡Gracias!

Pruebe con este patrón (tenga en cuenta la X al final y la ‘T’ en el medio):

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

De la documentación de SimpleDateFormat de Java:

Zona horaria ISO 8601:

Para el análisis sintáctico, “Z” se analiza como el designador de zona horaria UTC.

Y, de la parte donde describe los diferentes personajes:

X – Zona horaria – Huso horario ISO 8601

EDITAR

Si usa Android, entonces “X” no es compatible.

Puedes usar este patrón (nota Z es un literal ahora):

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

Pero luego obtendrá la fecha en su zona horaria actual y necesitaría convertirla a UTC si fuera necesario.

tl; dr

Omita el patrón de formateo. El formato estándar ISO 8601 se usa por defecto.

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

ISO 8601

Su formato de cadena está formalmente definido por el estándar ISO 8601 .

Básicamente su pregunta es un duplicado de esta, Convirtiendo la Cadena que cumple con ISO 8601 a java.util.Date .

Alternativas

La respuesta de eugenioy es correcta.

Pero debe saber que las antiguas clases java.util.Date/.Calendar/java.text.SimpleDateFormat incluidas con Java son notoriamente problemáticas y deben evitarse.

Clases pasadas de moda

Esas viejas clases ahora están pasadas de moda, primero por la biblioteca Joda-Time de terceros y ahora por el nuevo paquete java.time ( Tutorial ) integrado en Java 8 y posterior (inspirado en Joda-Time, definido por JSR 310 , extendido por el proyecto ThreeTen-Extra ).

Tanto java.time como Joda-Time usan el estándar ISO 8601 como sus valores predeterminados al analizar / generar representaciones de cadena de valores de fecha y hora. Por lo tanto, el código es simple, no hay necesidad de objetos formateadores personalizados. No hay necesidad de todo ese formato de twiddling que causó su excepción.

Zona horaria

Tanto java.time como Joda-Time tienen una clase zonal de fecha y hora que comprende su zona horaria asignada (a diferencia de java.util.Date). Si no asigna uno, se asigna la zona horaria predeterminada actual de la JVM.

Tenga en cuenta que la zona horaria predeterminada actual de la JVM puede cambiar en cualquier momento . Puede cambiar al momento de la implementación, por defecto a cualquier configuración del sistema operativo del host. Y puede cambiar en cualquier momento durante el tiempo de ejecución cuando cualquier código en cualquier subproceso de cualquier aplicación dentro de la JVM llama a TimeZone.setDefault . Así que es mejor asignar explícitamente una zona horaria deseada / esperada.

java.time

La Z en el final de su cadena es la abreviatura de Zulu y significa UTC. La clase Instant puede analizar directamente ese formato, para representar un momento en la línea de tiempo en UTC con una resolución en nanosegundos.

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

Cambie la zona horaria de UTC a alguna zona horaria deseada / esperada.

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

Si realmente necesita un java.util.Date para la interoperabilidad, conviértalo.

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

Joda-Time

El proyecto Joda-Time ahora está en modo de mantenimiento, y el equipo recomienda la migración a las clases java.time:

Tenga en cuenta que desde Java SE 8 en adelante, los usuarios deben migrar a java.time (JSR-310), una parte central del JDK que reemplaza este proyecto.

Código de ejemplo usando 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 ) ; 

Si realmente necesita un java.util.Date para la interoperabilidad, conviértalo.

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