Días que no existen en Oracle: En 1582…

En el post de hoy queremos compartir una curiosidad que hemos encontrado trabajando con campos de tipo fecha en Oracle. ¡¡¡¡Hay varios días que no existen en la BBDD!!!!

Esto se debe al cambio de calendario que se produjo en 1582. Hasta entonces, desde el año 46 aC, se usaba el calendario juliano, instaurado por Julio César. En ese año se instauró el calendario que actualmente usamos, el calendario gregoriano, promovido por el Papa Gregorio XIII. En esa transición se perdieron 10 días, desde el 5 de Octubre de 1582 hasta el 14 de Octubre de 1582.

Podemos comprobarlo en Oracle de la siguiente manera:

SQL> select to_date(’12/10/1582′,’dd/mm/yyyy’) from dual;

TO_DATE(

——–

15/10/82

La BBDD Oracle ignora estos días que no existen y toma como día real el primer día hábil después de ellos, el 15 de octubre de 1582, pero no devuelve un error al referirse a ellos. En cambio, si se busca un día “que sí existe”, se muestra correctamente.

SQL> select to_date(’01/10/1582′,’dd/mm/yyyy’) from dual;

TO_DATE(

——–

01/10/82

Los días que no existen se pueden comprobar con un sencillo programa en PL/SQL, comparando con los días en el calendario Juliano, que sí que existen.

SQL> set serveroutput on

SQL> DECLARE

  2     fecha_inicio DATE := to_date(’01/10/1582′,’dd/mm/yyyy’);

  3     fecha_fin DATE := to_date(’20/10/1582′,’dd/mm/yyyy’);

  4     fecha DATE;

  5  BEGIN

  6     dbms_output.put_line(‘Fecha inicio: ‘ || to_char(fecha_inicio,’dd/mm/yyyy’));

  7     dbms_output.put_line(‘Fecha inicio Juliano: ‘ || to_char(fecha_inicio,’j’));

  8     dbms_output.put_line(‘Fecha fin: ‘ || to_char(fecha_fin,’dd/mm/yyyy’));

  9     dbms_output.put_line(‘Fecha fin Juliano: ‘ || to_char(fecha_fin,’j’));

 10     FOR i IN to_char(fecha_inicio,’j’)..to_char(fecha_fin,’j’) LOOP

 11        select to_date(i,’j’) Into fecha from dual;

 12        dbms_output.put_line(to_char(fecha,’dd/mm/yyyy’) || ‘        ‘ || to_char(fecha,’j’));

 13     END LOOP;

 14  END;

 15  /

Fecha inicio: 01/10/1582

Fecha inicio Juliano: 2299157

Fecha fin: 20/10/1582

Fecha fin Juliano: 2299166

01/10/1582        2299157

02/10/1582        2299158

03/10/1582        2299159

04/10/1582        2299160

15/10/1582        2299161

16/10/1582        2299162

17/10/1582        2299163

18/10/1582        2299164

19/10/1582        2299165

20/10/1582        2299166

Procedimiento PL/SQL terminado correctamente.

Se puede comprobar qué ocurre cuando se intenta utilizar una de las fechas que no existen, por ejemplo en una operación de INSERT.

SQL> CREATE TABLE prueba_fechas (fecha DATE);

Tabla creada.

SQL> INSERT INTO prueba_fechas VALUES (to_date(’12/10/1582′,’dd/mm/yyyy’));

1 fila creada.

SQL> SELECT * FROM prueba_fechas;

FECHA

——–

15/10/82

Deseamos que este post os haya sido de utilidad.

Nos vemos en próximos posts,

Equipo de Base de datos

Fuentes:

CCC 11g Release 1 (11.1) (https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1838)

Calendario gregoriano. Wikipedia, La enciclopedia libre. Desde https://es.wikipedia.org/wiki/Calendario_gregoriano

Calendario juliano. Wikipedia, La enciclopedia libre. Desde https://es.wikipedia.org/wiki/Calendario_juliano