[C con Clase] Manejar Timestamp oracle

Salvador Pozo salvador en conclase.net
Mie Sep 8 15:18:28 CEST 2010


El pasado 2010-09-08 08:05:07, josu escribió:
 
j> Yo leo de una BBDD Oracle varios timestamp del tipo '2010-08-09
j> 09:00:00.00000' como un string.
j> Mi problema es que quiero realizar operaciones sobre ellos, del tipo
j> minutos entre dos timestamp... Vamos que me vendria de perlas pasar ese
j> string a un time_t, pero no tengo ni idea de cómo
j> La idea es intentar evitar la conversión manualmente, ¿existe alguna
j> funcion que pueda realizar esto?

Hola:

Se me ocurren dos soluciones (en principio) para este problema.

1) Suponiendo que Oracle disponga de mecanismos para resolver consultas SQL, lo más sencillo sería dejarle a él ese trabajo. Al menos eso es lo que suelo hacer yo en MySQL. Crear una consulta aprovechando las funciones SQL, del tipo:

mysql> select timediff("2010-09-08 14:00:00.0","2010-09-08 14:50:00.0") AS dif;
+-----------+
| dif       |
+-----------+
| -00:50:00 |
+-----------+
1 row in set (0.00 sec)

2) La otra opción es más laboriosa, y consistiría en convertir esa cadena a un valor de tipo

Para ello necesitamos dividir la cadena para rellenar adecuadamente una estructura "tm", concretamente, los primeros seis campos. El resto los dejamos a cero:

struct tm
{
        int     tm_sec;         /* Seconds: 0-59 (K&R says 0-61?) */
        int     tm_min;         /* Minutes: 0-59 */
        int     tm_hour;        /* Hours since midnight: 0-23 */
        int     tm_mday;        /* Day of the month: 1-31 */
        int     tm_mon;         /* Months *since* january: 0-11 */
        int     tm_year;        /* Years since 1900 */
        int     tm_wday;        /* Days since Sunday (0-6) */
        int     tm_yday;        /* Days since Jan. 1: 0-365 */
        int     tm_isdst;       /* +1 Daylight Savings Time, 0 No DST,
                                 * -1 don't know */
};

Podemos colocar ceros en las posiciones de los separadores:
           1111111111222222
 01234567890123456789012345
'2010-08-09 09:00:00.00000'

En este caso, en las posiciones 4, 7, 10, 13, 16 y 19.

A continuación, usamos atoi para convertir cada subcadena al valor entero correspondiente:

char t_oracle[25] = "2010-08-09 09:00:00.00000";
tm tiempo;

t_oracle[4] = t_oracle[7] = t_oracle[10] = t_oracle[13] = 
t_oracle[16] = t_oracle[19] = 0;

tiempo.tm_sec = atoi(&t_oracle[17]);
tiempo.tm_min = atoy(&t_oracle[14]);
tiempo.tm_hour = atoi(&t_oracle[11]);
tiempo.tm_mday = atoi(&t_oracle[8]);
tiempo.tm_mon = atoi(&t_oracle[5])-1;
tiempo.tm_year = atoi(&t_oracle[0]-1900);

Cuidado con el mes y el año. La estructura numera los meses de 0 a 11, 0 para enero, 11 para diciembre. Los años se cuentan a partir de 1900, de modo que hay que restar 1900 al año.

Por último, usamos la función mktime:
http://c.conclase.net/librerias/index.php?ansifun=mktime#inicio

en nuestro caso:
time_t tt_tiempo = mktime(&tiempo);

Podemos hacer operaciones con valores de este tipo, sumas y restas, y volver a crear una estructura time_t a partir de esos valores, usando la función "time":
http://c.conclase.net/librerias/index.php?ansifun=time#inicio

Hasta pronto.

-- 
Salvador Pozo (Administrador)
mailto:salvador en conclase.net


Más información sobre la lista de distribución Cconclase