2012-08-17 21 views
10

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.Conversión String-Date con nanosegundos

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 un UTC date y lo 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 resultados en: Today = 17.08.2012 07:41:59:0000000 17 Aug 2012 04:41:59 GMT cuales son incorrectos.

He intentado configurar SDF's timezone a 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 me puede dar algunas explicaciones/código de muestra, estaría muy agradecido. Gracias de antemano

Respuesta

16

El resultado que está obteniendo es absolutamente correcto.

Analicemos esto:

17.08.2012 05:35:19:7600000 
  • 17: Día del mes (17a)
  • 08: Mes del año (agosto)
  • 2012: Año (2012)
  • 05: Hora del día (5am)
  • 35: Minuto de hora (: 35)
  • 19: Segundo minuto (: 19)
  • 7600000: milisegundos de segundo (7.600.000)

Ahora, la forma en la máquina virtual ve esto es que se está declarando la hora del día como 05:35:19 am, a continuación, añadir 7.600.000 milisegundos a ella. 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á 3 horas detrás de su resultado.)

Si desea conservar el :7600000, a mi entender 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 guardar los valores < 1000.

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 un solo long en el objeto Date).

+0

Gracias! Después de setTimeZone (TimeZone.getTimeZone ("UTC")) todo estuvo bien. En cuanto a los milisegundos, creo que los restableceré a 0. No creo que importe en mi caso. El ejemplo que di fue una respuesta de un servidor, como hora UTC ahora, tendré que ver por qué devuelve esos milisegundos. – Rhadoozooz

+0

¡Me alegro de que hayas descubierto el problema! ¡Buena suerte! :) – Eric

+2

@Eric BTW buena explicación, apreciable. –

6
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; 
} 

Pruebe esto.

+0

En postFormater escriba su formato –

2

Esto es lo que necesita (pero va a perder información milisegundos):

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

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

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

pruébelo:

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