¿Qué es este formato de fecha? 2011-08-12T20: 17: 46.384Z

Tengo la siguiente fecha: 2011-08-12T20:17:46.384Z . ¿Qué formato es esto? Estoy tratando de analizarlo con Java 1.4 a través de DateFormat.getDateInstance().parse(dateStr) y estoy obteniendo

java.text.ParseException: fecha inusable: “2011-08-12T20: 17: 46.384Z”

Creo que debería usar SimpleDateFormat para analizar, pero primero tengo que saber la cadena de formato. Todo lo que tengo para eso hasta ahora es yyyy-MM-dd , porque no sé lo que significa T en esta cadena, ¿algo relacionado con la zona horaria? Esta cadena de fecha proviene de la etiqueta lcmis:downloadedOn muestra en el tipo de medio de historial de descarga de Archivos CMIS .

La T es simplemente literal para separar la fecha de la hora, y la Z significa “compensación de hora cero”, también conocida como “hora Zulu” (UTC). Si sus cadenas siempre tienen una “Z”, puede usar:

 SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); format.setTimeZone(TimeZone.getTimeZone("UTC")); 

O usando Joda Time , puede usar ISODateTimeFormat.dateTime() .

tl; dr

La cadena de entrada usa el formato estándar ISO 8601 .

 Instant.parse ( "2011-08-12T20:17:46.384Z" ) 

ISO 8601

Este formato está definido por el práctico estándar sensible, ISO 8601 .

La T separa la porción de fecha de la porción de hora del día. La Z en el extremo es corta para Zulu y significa UTC .

java.time

Las antiguas clases de fecha y hora incluidas con las primeras versiones de Java han demostrado ser mal diseñadas, confusas y problemáticas. Evítales.

En su lugar, utilice el marco java.time integrado en Java 8 y posterior. Las clases java.time suplantan a las antiguas clases de fecha y hora y a la exitosa biblioteca Joda-Time.

Las clases java.time usan ISO 8601 de forma predeterminada al analizar / generar representaciones textuales de valores de fecha y hora.

La clase Instant representa un momento en la línea de tiempo en UTC con una resolución de nanosegundos . Esa clase puede analizar directamente su cadena de entrada sin molestarse en definir un patrón de formateo.

 Instant instant = Instant.parse ( "2011-08-12T20:17:46.384Z" ) ; 

Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases heredadas de fecha y hora como java.util.Date , Calendar y SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

¿Dónde obtener las clases de java.time?

  • Java SE 8 , Java SE 9 y posterior
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Androide
    • Versiones posteriores de las implementaciones del paquete de Android de las clases java.time.
    • Para Android anterior, el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Consulte Cómo utilizar ThreeTenABP ….

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. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y más .

No estoy seguro sobre el análisis de Java, pero eso es ISO8601: http://en.wikipedia.org/wiki/ISO_8601

Hay otras formas de analizarlo en lugar de la primera respuesta. Para analizarlo:

(1) Si desea obtener información sobre la fecha y la hora, puede analizarla en un objeto ZonedDatetime (desde Java 8 ) o Date (antiguo):

 // ZonedDateTime's default format requires a zone ID(like [Australia/Sydney]) in the end. // Here, we provide a format which can parse the string correctly. DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME; ZonedDateTime zdt = ZonedDateTime.parse("2011-08-12T20:17:46.384Z", dtf); 

o

 // 'T' is a literal. // 'X' is ISO Zone Offset[like +01, -08]; For UTC, it is interpreted as 'Z'(Zero) literal. String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX"; // since no built-in format, we provides pattern directly. DateFormat df = new SimpleDateFormat(pattern); Date myDate = df.parse("2011-08-12T20:17:46.384Z"); 

(2) Si no le importa la fecha y la hora y solo desea tratar la información como un momento en nanosegundos, puede usar Instant :

 // The ISO format without zone ID is Instant's default. // There is no need to pass any format. Instant ins = Instant.parse("2011-08-12T20:17:46.384Z"); 

La manera más fácil de resolver esto es reemplazar la "T" por " " y eliminar .384Z .

A continuación se muestra una ilustración de cómo lograr eso:

 public static String getTime(String time) { if (time != null) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (time.toUpperCase().contains("T") && time.toUpperCase().contains("Z")) { time = time.toUpperCase().replace("T", " "); String[] str = time.split("\\."); if (str.length != 0) { return str[0]; } } try { Date date = new Date(time); time = simpleDateFormat.format(date); } catch (Exception e) { // } } return time; }