La conversión String-Date con nanosegundos

He estado luchando durante un tiempo con este código para una aplicación de Android y no puedo entenderlo. He leído y probado todas las soluciones que encontré en stackoverflow y otros lugares, pero todavía no tuve suerte.

Lo que quiero hacer es tener una función para convertir una cadena como "17.08.2012 05:35:19:7600000" a una fecha UTC y una función que toma una UTC date y la convierte en una cadena como esa.

 String value = "17.08.2012 05:35:19:7600000"; DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss:SSSSSSS"); try { Date today = df.parse(value); System.out.println("Today = " + df.format(today) + " " + today.toGMTString()); } catch (ParseException e) { e.printStackTrace(); } 

Esto da como resultado: Today = 17.08.2012 07:41:59:0000000 17 Aug 2012 04:41:59 GMT que son ambos incorrectos.

Intenté configurar SDF's timezone en UTC , sin suerte.
Otra cosa que noté: si hago df.setLenient(false);
Me da: java.text.ParseException: Unparseable date: "17.08.2012 05:35:19:7600000" .

Si alguien puede proporcionarme algunas explicaciones / código de muestra, estaría muy agradecido. Gracias por adelantado

El resultado que está obteniendo es absolutamente correcto.

Analicemos esto:

 17.08.2012 05:35:19:7600000 
  • 17: Día del mes (17)
  • 08: mes del año (agosto)
  • 2012: año (2012)
  • 05: Hora del día (5 a.m.)
  • 35: Minuto de hora (: 35)
  • 19: segundo de minuto (: 19)
  • 7600000: milisegundos de segundo (7,600,000)

Ahora, la forma en que VM ve esto es que usted está declarando la hora del día como 5:35:19 a.m., y luego le agrega 7,600,000 milisegundos. 7,600,000 milisegundos = 7,600 segundos = 2 horas, 6 minutos, 40 segundos. 5:35:19 a.m. + 02:06:40 = 7:41:59 a.m. (y 0 milisegundos). Este es el resultado que está obteniendo. (También parece que no está configurando la zona horaria correctamente, por lo que la cadena GMT está a 3 horas de su resultado).

Si desea conservar el :7600000 , que yo sepa, esto no es posible. Como esto se puede simplificar en segundos, la máquina virtual lo reducirá automáticamente en los otros incrementos de tiempo. Los milisegundos ( SSSS ) deben ser para almacenar valores <1000.

Le sugiero que cree un nuevo SimpleDateFormat para su salida; pero recuerde que los milisegundos se absorberán en los otros momentos (ya que están almacenados como una única long en el objeto Date ).

  private String convertDate(String cdate) { SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss:SSSSSSS"); SimpleDateFormat postFormater = new SimpleDateFormat("yyyy-MM-dd"); Date convertedDate; try { convertedDate = dateFormat.parse(cdate); cdate = postFormater.format(convertedDate); } catch (ParseException e) { Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_SHORT).show(); } return cdate; } 

Prueba esto.

Esto es lo que necesita (pero perderá información en milisegundos):

 "dd.MM.yyyy HH:mm:ss.'000000'" 

Si usó "dd.MM.yyyy HH:mm:ss.SSSSSS" , obtendría tres ceros a la izquierda durante sus milisegundos.

Si usó "dd.MM.yyyy HH:mm:ss.SSS'000'" , entonces podría formatear una fecha, pero no analizar ninguna fecha.

Pruébalo:

 public static void main(String[] args) throws ParseException { printDate("dd.MM.yyyy HH:mm:ss.SSS");//02.05.2010 21:45:58.073 printDate("dd.MM.yyyy HH:mm:ss.SSSSSS");//02.05.2010 21:45:58.000073 printDate("dd.MM.yyyy HH:mm:ss.SSS'000'");//02.05.2010 21:45:58.073000 printDate("dd.MM.yyyy HH:mm:ss.'000000'");//02.05.2010 21:45:58.000000 tryToParseDate("dd.MM.yyyy HH:mm:ss.SSS");//good tryToParseDate("dd.MM.yyyy HH:mm:ss.SSSSSS");//good tryToParseDate("dd.MM.yyyy HH:mm:ss.SSS'000'");//bad tryToParseDate("dd.MM.yyyy HH:mm:ss.'000000'");//good } private static void printDate(String formatString) { Date now = new Date(); SimpleDateFormat format = new SimpleDateFormat(formatString); String formattedDate = format.format(now); // print that date System.out.println(formattedDate); } private static void tryToParseDate(String formatString) { Date now = new Date(); SimpleDateFormat format = new SimpleDateFormat(formatString); String formattedDate = format.format(now); // try to parse it again try { format.parse(formattedDate); System.out.println("good"); } catch (ParseException e) { System.out.println("bad"); } }