2011-10-02 30 views
26

Tengo una cadena entrando con este formato: YYYY-MM-DD-HH.MM.SS.NNNNNN La indicación de fecha y hora proviene de una base de datos DB2. Necesito analizarlo en un java.sql.Timestamp y NO perder ninguna precisión. Hasta ahora no he podido encontrar el código existente para analizar eso en microsegundos. SimpleDateFormat devuelve una fecha y solo analiza a milisegundos. Miró a JodaTime brevemente y no vio que eso funcionaría tampoco.Convertir Java String en sql.Timestamp

+2

Si la marca de tiempo proviene de una base de datos DB2, ¿por qué estás leyendo como una cadena en lugar de leerlo como una marca de tiempo directamente? –

+1

La marca de tiempo proviene de la base de datos y un cliente nos la devuelve para una lectura con clave. – Dan

+1

Si está utilizando la marca de tiempo para una lectura con clave, y presumiblemente lo está enviando primero al cliente, podría considerar convertirlo a un largo de nanosegundos y luego leerlo nuevamente, en lugar de un valor de cadena. es decir, envíe 'long l = ts.getTime()' y luego vuelva a leerlo con 'new Timestamp (l)'. Incluso podría serializar este valor para ahorrar espacio en el cable (pero en este caso perdería la capacidad de escritura humana). – Luciano

Respuesta

58

¿Ha intentado utilizar Timestamp.valueOf(String)? Parece que se debe hacer casi exactamente lo que quiere - sólo tiene que cambiar el separador entre la fecha y la hora a un espacio, y los más entre horas y minutos, y los minutos y horas, a dos puntos:

import java.sql.*; 

public class Test { 
    public static void main(String[] args) { 
     String text = "2011-10-02 18:48:05.123456"; 
     Timestamp ts = Timestamp.valueOf(text); 
     System.out.println(ts.getNanos()); 
    } 
} 

Suponiendo que ya haya validado la longitud de cadena, esto se convertirá en el formato correcto:

static String convertSeparators(String input) { 
    char[] chars = input.toCharArray(); 
    chars[10] = ' '; 
    chars[13] = ':'; 
    chars[16] = ':'; 
    return new String(chars); 
} 

Alternativamente, analizar hasta milisegundos mediante la adopción de una subcadena y el uso de tiempo Joda o SimpleDateFormat (I enormemente prefiero Joda Time , pero tu kilometraje puede variar). A continuación, tome el resto de la cadena como otra cadena y analícela con Integer.parseInt. A continuación, puede combinar los valores con bastante facilidad:

Date date = parseDateFromFirstPart(); 
int micros = parseJustLastThreeDigits(); 

Timestamp ts = new Timestamp(date.getTime()); 
ts.setNanos(ts.getNanos() + micros * 1000); 
+0

¿cómo maneja Timestamp.valueOf (String) en la zona horaria? – fudy

7

Usted podría utilizar Timestamp.valueOf(String). La documentación indica que comprende las marcas de tiempo en el formato yyyy-mm-dd hh:mm:ss[.f...], por lo que puede necesitar cambiar los separadores de campo en la cadena entrante.

Por otra parte, si va a hacer eso, entonces podría analizarlo usted mismo y usar el método setNanos para almacenar los microsegundos.

1

yo creo que hay que hacer esto:

  1. Convierte everythingButNano usando SimpleDateFormat o similar para everythingDate.
  2. nano Convertir usando Long.valueof (nano)
  3. Convertir everythingDate a una marca de tiempo con el nuevo orden de llegada (everythingDate.getTime())
  4. Establecer los nanos de marca de hora con Timestamp.setNano()

Opción 2 Convierte al formato de fecha indicado en la respuesta de Jon Skeet y úsalo.

4

Esta es la forma pretendida para hacerlo:

String timestamp = "2011-10-02-18.48.05.123"; 
DateFormat df = new SimpleDateFormat("yyyy-MM-dd-kk.mm.ss.SSS"); 
Date parsedDate = df.parse(timestamp); 

Es cierto, que sólo tiene una resolución de milisegundos, pero en todos los servicios más lentos que Twitter, que es todo lo que necesita, sobre todo porque la mayoría de las máquinas no hacen incluso rastrea hasta los nanosegundos reales.

1

Si se obtiene el tiempo como una cadena en formato tales como 1441963946053 simplemente podría hacer algo como lo siguiente:

//String timestamp; 
Long miliseconds = Long.valueOf(timestamp); 
Timestamp ti = new Timestamp(miliseconds);