lunes, 18 de febrero de 2008

Operaciones con fechas

Aqui algunos ejemplos para adicionar y sustraer días y meses y encontrar la diferencia entre fechas en Oracle. Estos ejemplos toman el resultado de la tabla "dual. La tabla Dual es una tabla virtual que existe en todas las Bases de datos Oracle. Muchas veces hemos usado la consulta SELECT sysdate FROM dual; la cual simplemente nos retorna la fecha y hora actual.

Ajustar Dias, Semanas, Horas y minutos


Para adicionar y sustraer días a una fecha, simplemente usamos los signos + o - respectivamente. Algunos ejemplos:
SQL> SELECT sysdate + 7 FROM dual;
SYSDATE+
-------
25/09/06
SQL> SELECT sysdate - 30 FROM dual;
SYSDATE-
--------
19/08/06
SQL> SELECT to_char(sysdate - 14, 'MM/DD/YYYY HH:MI AM') FROM dual;
TO_CHAR(SYSDATE-14,
-------------------
09/04/2006 11:41 AM
En el primer ejemplo, vemos que la consulta retorna la fecha siete días apartir de hoy. La segunda retorna la fecha de hace 30 días. En la tercera, se ha usado la función de conversión to_char, para ver las horas y minutos. Esto nos muestra que mientras la fecha, ha cambiado, el tiempo no cambia.
Los ejemplos primero y tercero ademas muestran como el adicionar días, puede ser útil para computar semanas. Si ud desea simplificar el computo de semanas, podías usar querys de este tipo:
SQL> SELECT sysdate + (7 * 3) FROM dual;
SYSDATE+
--------
09/10/06
Así mismo, para trabajar con horas ud podría usar fracciones de día. La forma más simple para mostrar esto es dividiendo por 24, que es el numero de horas diarias. Aunque el parentesis no es necesario, permite evidenciar con más claridad la sentencia
Aqui, se muestra la hora actual y luego la hora actual mas dos horas:
SQL> SELECT to_char(sysdate, 'HH:MI AM') FROM dual;
TO_CHAR(
--------
02:00 PM
SQL> SELECT to_char(sysdate + (2/24), 'HH:MI AM') FROM dual;

TO_CHAR(
--------
04:00 PM

Una alternativa a este método es el uso de la función numtodsinterval. El anterioir ejemplo puede ser reescrito de la siguiente manera (la función numtodsinterval viene incorporada en la BD apartir de oracle 9i):
SQL> SELECT to_char(sysdate + numtodsinterval(2, 'HOUR'), 'HH:MI AM')
FROM dual;
TO_CHAR(
---
02:00 PM
Aquí la función numtodsinterval está haciendo el trabajo de dividir 2/24 horas. Las opciones válidas para esta función son: ‘DAY’, ‘HOUR’, ‘MINUTE’, o ‘SECOND’. Aquí un ejemplo usando ‘MINUTE’. Cuando se trabaja con minutos la función numtodsinterval es mucho más legible.
SQL> SELECT to_char(sysdate + numtodsinterval(45, 'MINUTE'), 'HH:MI AM')FROM dual;
TO_CHAR(
--------
03:19 PM

Ajustar meses y años


Para trabajar con meses y años (cada uno de los cuales puede variar en número de días) Oracle ofrece la función numtoyminterval. Esta trabaja en forma similar a la función numtodsinterval mencionada antes tomando un numero y una cadena string. Las opciones válidas para esta función son: ‘YEAR’ or ‘MONTH’.
SQL> SELECT to_char(sysdate + numtoyminterval(5, 'MONTH'), 'MM/DD/YYYY') FROM dual;
TO_CHAR(SY
----------
02/18/2007
SQL> SELECT to_char(sysdate + numtoyminterval(2, 'YEAR'), 'MM/DD/YYYY') FROM dual;
TO_CHAR(SY
----------
09/18/2008

Comparar fechas

Suponga que deseamos comparar algunas fechas y encontrar el numero de días entre ellas. Para ver este resultado en días, simplemente basta con usar el operador -, de la siguiente manera:
SQL> SELECT TO_DATE('11/04/2006', 'MM/DD/YYYY') - sysdate FROM dual;
TO_DATE('11/04/2006','MM/DD/YYYY')-SYSDATE
------------------------------------------
46,3796528
El resultado es expresado en días, incluyendo horas fraccion de horas. Por supuesto si se desea semanas, se podría dividir el resultado entre 7. De manera similar, si se desea obtener horas, se debería multiplicar por 24, pero si se desea meses, entonces se podría usar la función months_between.
SQL> SELECT months_between(sysdate, to_date('01/01/2006', 'MM/DD/YYYY')) FROM dual;
MONTHS_BETWEEN(SYSDATE,TO_DATE('01/01/2006','MM/DD/YYYY'))
----------------------------------------------------------
8,56846625

Retornar la mayor y menor fecha dentro de un conjunto

Las funciones greatest y least pueden ser usadas en fechas para retornar la menor o la mayor fecha.
SQL> SELECT greatest(sysdate,sysdate+1, to_date('09/11/2005','MM/DD/YYYY'), to_date('12/25/2005','MM/DD/YYYY'))FROM dual;
GREATEST
--------
19/09/06
SQL> SELECT least(sysdate,sysdate+1,to_date('09/11/2005','MM/DD/YYYY'), to_date('12/25/2005','MM/DD/YYYY'))FROM dual;
LEAST(SY
--------
11/09/05


Cual es el último día de este mes?


La función last_day retorna el último día del mes pasado como parámetro.
SQL> select last_day(sysdate) from dual;
LAST_DAY
--------
30/09/06


Siguiente día de la semana despues de una fecha


La función next_day retorna la fecha de la próxima ocurrencia de un día de la semana(’Monday’, ‘Tuesday’, etc.) después de una fecha dada. ejemplo: consultar la fecha del próximo domingo:
SQL> select next_day(sysdate,'Domingo') from dual;
NEXT_DAY
--------
24/09/06

7 comentarios:

Emmanuel dijo...

Hola.
Me parece muy buena la información de tu sitio, y quisiera saber si hay una forma de sumar y restar fechas y horas de forma manual sin usar las funciones numtodsinterval y numtoymininterval, esto es en el caso de que me encuentre con una base en 8i.

Gracias de antemano y felicidades por el sitio!.

Anónimo dijo...

simplemente excelente, muchas gracias, fue de gran ayuda. muy claro directo, preciso y los ejemplos funcionan.

Anónimo dijo...

Justo lo que buscaba. Muchas gracias

Anónimo dijo...

Muy bueno!!!!!
Me ha sido muy util, muchas gracias

Anónimo dijo...

Muy Bueno graciassss

Anónimo dijo...

justo lo que andaba buscando... muchisimas gracias!!!!!!!

Isabella

rsc dijo...

¡Muy completo y muy buenos ejemplos! Por cierto, una curiosidad sobre las DATE en Oracle: Julian Day y el SGBD de Oracle