PL/SQL: convertir varchar a hora para luego obtener diferencia

publicado por: Anonymous

Tengo guardado en una tabla un varchar que representa una hora, por ejemplo ’23:30′. Lo que quiero hacer es convertir ese valor a hora y luego calcular la diferencia con respecto a sysdate… ¿Habrá alguna forma de hacerlo?

Convierto la variable con to_date pero muestra una fecha que no tiene nada que ver con la hora.

solución

Toma en cuenta que Oracle no tiene un tipo que represente solamente una hora. Por esta razón, cuando usas to_date(campo_hora, 'HH24:MI') (asumo que algo así debistes hacer), Oracle no solo te puede devolver la hora, sino que te devuelve también una fecha. Y por defecto, te devolverá el primer día del mes corriente.

Por ejemplo, si ejecutas la sentencia siguiente, tomando en cuenta que la fecha hoy es 2016-11-25:

select to_date('23:30', 'HH24:MI') from dual

… te devolverá la siguiente fecha: 2016-11-01 23:30:00.

Ahora bien, si tu objetivo es de comparar la porción hora del sysdate con tu campo, necesitas convertir tu campo a una fecha que tenga el mismo día que sysdate para que la diferencia sea solamente con la hora. Esto lo puedes lograr de esta manera (asumiendo que campo_hora contiene el valor '23:30'):

select to_date(to_char(sysdate, 'YYYY-MM-DD') || ' ' || campo_hora, 'YYYY-MM-DD HH24:MI')
  from dual

…asumiendo que ejecutas la sentencia hoy (2016-11-25), el resultado será la fecha siguiente: 2016-11-25 23:30:00.

Ahora sí puedes comparar esa fecha con sysdate para obtener la diferencia de horas.

Por ejemplo, ahora puedes hacer:

select to_date(to_char(sysdate, 'YYYY-MM-DD') || ' ' || campo_hora, 'YYYY-MM-DD HH24:MI')
       - sysdate
  from dual

… lo que te devolverá una decimal que representa la diferencia en cantidad de días, algo como: 0.60605..., o sea, una fracción de un día.

Ahora la pregunta es saber en qué formato deseas ver la diferencia, puesto que no lo especificastes. Pero digamos que quieres ver la diferencia en horas, entonces tienes que multiplicar por 24:

select (to_date(to_char(sysdate, 'YYYY-MM-DD') || ' ' || campo_hora, 'YYYY-MM-DD HH24:MI')
       - sysdate) * 24
  from dual

… o si quieres ver la diferencia en minutos, entonces hay que multiplicar por 24 * 60:

select (to_date(to_char(sysdate, 'YYYY-MM-DD') || ' ' || campo_hora, 'YYYY-MM-DD HH24:MI')
       - sysdate) * 24 * 60
  from dual

… y así por el estilo para segundos también…


Otra opción es que Oracle también tiene un tipo para representar intervalos. Se llama INTERVAL DAY TO SECOND. Si te interesa trabajar con este tipo, entonces puedes hacer una consulta como la siguiente:

select TO_DSINTERVAL('0 ' || campo_hora || ':00')
       - NUMTODSINTERVAL(sysdate - trunc(sysdate), 'day')
  from dual

Si ejecutas la consulta a las 9:40am mas o menos, esto te devolverá un valor parecido a: +00 13:50:30.000000, que representa una diferencia de 13 horas, 50 minutos, 30 segundos, etc.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published.