
Lo que fue el año 2.000
IDENTIFICATION DIVISION. (Introduccion)
¿ Porque es un
problema la llegada del año 2.000 ?. Cuando desde Cobol le pedimos al Sistema que nos de
la fecha actual, ésta nos viene en formato AAMMDD y los dígitos correspondientes al
milenio los deprecia, con lo cual cuando intentamos comparar fechas de distinto siglo el
resultado puede ser erróneo, por ejemplo:
Que fecha sería mayor 19991020 (20 de
Octubre de 1.999) o 20000115 (15 de Enero del 2.000), en teoría es mayor la que hace
referencia a un año mayor, pero al depreciar los 2 primer dígitos y solo ofrecernos
991020, para la primera y 000115 para la segunda resulta que la fecha que hace referencia
a 1999 la considera mayor.
Vamos a ver todo ésto lo mas claramente posible (quizás para la mayoría todo ésto sea muy evidente, pero intento que
para las personas que no lo sea, lo entiendan bien), para comprobar cuando una fecha es
mayor que otra, se comparan como si de un número entero se tratase, 991020 es mayor que
000115 (novecientos noventa y un mil veinte es mayor
que ciento quince).Pero si tuviéramos la fecha en
formato completo AAAAMMDD, el resultado sería distinto, porque 20000115 es mayor que
19991020(veinte millones ciento quince es mayor que
diecinueve millones novecientos noventa y un mil veinte).
Formato
AAMMDD |
991.020 |
000.115 |
Formato
AAAAMMDD |
20.000.115 |
19.991.020 |
¿ Porque se guardan las fechas en formato AAMMDD y no como se leen en español DDMMAA ?. Creo que con
la respuesta anterior está todo dicho, si el formato fuera el español no podriamos
operar como si fuesen números, ya que 210598 sería mayor que 190598, pero en cambio
sería menor que 010698, y la realidad nos dice que eso no es así, la fecha mayor sería
010698, luego 210598 y por último 190598.
Para verlo todo un poco mas claro mirad a
la tabla siguiente, están ordenados de mayor a menor, fijaros que hay diferencia entre
los dos formatos, mientras para el DDMMAA la fecha 21 de Mayo de 1.998 sería la mayor,
para el formato AAMMDD la mayor es el 1 de Junio de 1.998, por tanto la correcta. (el
hecho de poner el separador de miles es para que podais apreciar mejor la cifra mayor,
imaginándola como un número entero).
Formato
DDMMAA |
210.598 |
190.598 |
010.698 |
Formato
AAMMDD |
980.601 |
980.521 |
980.519 |
ENVIRONMENT DIVISION. (Desarrollo)
El análisis, es sin duda la parte mas importante de todo el proyecto, hay que tener bien inventariado
tanto los archivos a los que va a afectar, como a los programas que utilizan esos
archivos.
Obviamente la manera que tenemos cada
programador para hacer nuestro trabajo es muy diferente, por lo que entiendo que no todos
tendremos los mismos criterios ni la misma forma de enfocar nuestras aplicaciones o
proyectos. A continuación os detallo mis criterios:
- Trabajo en UNIX SVR4 con RM/COBOL 85 Versión 6.00.00, sin ninguna herramienta adicional.
- Todas las FD´s de los ficheros las tengo en archivos aparte que luego llamo con copy desde cada programa para evitarme
errores con los nombre de los campos.
- Los programas van en un directorio y los archivos en otro.
- La Working-Storage Section es común para todos los programas, igual nombre para las variables.
- En la Select nunca doy el lugar absoluto del archivo para tener mas libertad, es decir si el archivo
Clientes.dat se encuentra en el directorio /home/datos
y los programas están en /home/programas, la dirección a la que hago referencia sería "../datos/clientes.dat"
, de ésta manera si ahora en vez de estar todo colgado de /home lo estuviera de /pepe
, no habría ningún problema.
Bien, una vez hechas las consideraciones
oportunas pasamos al detalle del proyecto.
Es muy importante tener todo sobre papel, es decir un listado con todos los programas y lo
que hacen para no perderte, otro con todos los archivos y una carpeta con todas las FD´s
listadas (se que es un trabajo meticuloso, pero a la larga los resultados se obtienen y
los errores serán mínimos).
A continuación haremos una copia
de nuestros directorios de programas y archivos en otro lugar, en mi caso los originales
parten de /home , teniendo los programas en un directorio y los
archivos en otro, pues bien esa misma estructura se copia a /home1 o a
cualquier otro directorio, para ir haciendo los cambios sin entorpecer la labor de la
empresa.
Yo he preferido que tanto en pantalla como en los listados, la fecha siga apareciendo en 6 dígitos, por
varios motivos:
- El usuario no tendrá que modificar su
hábito de introducir fechas, sería mucho mas latoso para él introducir 8 dígitos que
6, además de su falta de costumbre y consiguiente probabilidad de error. Él no debe de
notar nada, menos problemas.
- En las cabeceras de los listados no hay
que hacer ninguna modificación.
- En el diseño de la pantalla no hay que
modificar, en alguna hasta sería un grave problema, puesto que están llenas y no cabe ni
una coma.
- Y por último. hay que pensar que en el
2.001 ya todo volverá a la normalidad (practicamente) porque volveremos a comparar fechas
del mismo siglo.
La solución que yo he tomado vale unicamente hasta el año 2.090 pero por desgracia para ese año....., de
todas formas solo cambiano un número de una de las rutinas problema resuelto.
DATA DIVISION. (Variables)
Para todo el proceso he creado 5 rutinas pequeñas que serán llamadas tantas veces como sea necesario
desde los programas.
Puesto que van a ir en todos los
programas os aconsejo que las pongais en un archivo y luego copy en todos los programas, si ya tenis algún archivo
pequeño que realice alguna tarea común y sea llamado desde los programas, pues lo implementais en éste y os
evitais poner otra copy .
Las variables necesarias para aplicar las
rutinas son las siguientes:
WORKING-STORAGE SECTION.
........
........
01 FECA PIC 9(6). (fecha 6 dígitos en castellano
DDMMAA).
01 FECO REDEFINES FECA.
02 FDIA PIC 99. (dia)
02 FMES PIC 99. (mes)
02 FANO PIC 99. (año)
01 FESPA
PIC 9(8). (fecha 8 dígitos en castellano DDMMAAAA).
01 FEXPA REDEFINES FESPA.
02 FPDIA PIC 99. (dia)
02 FPMES PIC 99. (mes)
02 FPSIG PIC 99. (siglo)
02 FPANO PIC 99. (año)
01 FEREV
PIC 9(8). (fecha 8 dígitos en inglés SSAAMMDD).
01 FEREX REDEFINES FEREV.
02 FRSIG PIC 99. (dia)
02 FRANO PIC 99. (mes)
02 FRMES PIC 99. (siglo)
02 FRDIA PIC 99. (año).
Si no utilizais
una Working común para todos vuestros programas, es conveniente introducir las variables
en un archivo y que sea llamado desde los programas dentro de la Working. Por supuesto los
nombre de las variables podeis cambiarlos, teniendo en cuenta cambiar también las
rutinas.
PROCEDURE DIVISION. (Rutinas)
A continuación os detallo las rutinas y una explicación de lo que hacen:
PROCEDURE
DIVISION.
........
........
A2000.
IF FANO < 90 MOVE 20 TO FPSIG FRSIG
ELSE MOVE 19 TO FPSIG
FRSIG.
MOVE FDIA TO FPDIA FRDIA.
MOVE FMES TO FPMES FRMES.
MOVE FANO TO FPANO FRANO. |
Esta rutina se encarga de adaptarnos una fecha de 6 dígitos con
formato DDMMAA a dos variables de 8 dígitos, FESPA en formato DDMMAASS y FEREV con
formato SSAAMMDD. (Comunmente llamo FESPA a un formato en castellano y a FEREV a uno en
inglés.
Observamos que la fecha que le damos siempres va en formato castellano DDMMAA. |
C2000.
MOVE FPDIA TO FRDIA.
MOVE FPMES TO FRMES.
MOVE FPANO TO FRANO.
MOVE FPSIG TO FRSIG. |
Partiendo de un formato de 8 dígitos en castellano y en la
variable FESPA, nos devuelve la variable FEREV con el formato inglés
SSAAMMDD. |
C2000R.
MOVE FRDIA TO FPDIA.
MOVE FRMES TO FPMES.
MOVE FRANO TO FPANO.
MOVE FRSIG TO FPSIG. |
Partiendo de un formato de 8 dígitos en inglés y en la variable
FEREV, nos devuelve la variable FESPA con el formato castellano
DDMMSSAA. |
DE8A6.
MOVE FPDIA TO FDIA.
MOVE FPMES TO FMES.
MOVE FPANO TO FANO. |
Partiendo de un formato de 8 dígitos en castellano y en la
variable FESPA, nos devuelve la variable FECA con el formato DDMMAA con 6 dígitos. |
DE8A6R.
MOVE FRDIA TO FDIA.
MOVE FRMES TO FMES.
MOVE FRANO TO FANO. |
Partiendo de un formato de 8 dígitos en inglés y en la variable
FEREV, nos devuelve la variable FECA con el formato DDMMAA con 6 dígitos. |
Ya veis que las rutinas son muy simples, pero si os acostumbrais, funcionan de maravilla.
El motivo de utilizar los dos formatos de fechas, es porque cuando el campo fecha de algún fichero
solo es informativo y no voy a operar con el lo pongo en formato castellano
DDMMSSAA, quizás no sea una buena opción pero como ya lo tenía así, no lo he cambiado. Si
utilizais siempre la fecha en formato inglés SSAAMMDD, os sobrarán algunas rutinas.
ANALISIS.
Llegados a éste punto, solo queda explicar los pasos y poner un sencillo ejemplo. Principalmente se
puede decir que tenemos dos pasos, la conversión de los archivos y la de los programas.
1. Conversión de archivos.
Para cada archivo generamos un pequeño programa que lea el archivo y lo genere en otro
con el campo fecha de 8 dígitos y el formato que hayamos elegido DDMMSSAA o
SSAAMMDD.
Movemos todos los campos de un fichero a otro y al campo fecha le aplicamos la primera
rutina la llamada A2000 , grabamos el nuevo registro y una vez concluido
cambiamos los nombres de los archivos.
IDENTIFICATION DIVISION.
PROGRAM-ID. CAMBIO.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ARCHIVOANTIGUO ASSIGN TO RANDOM
"ANTIGUO.DAT" ORGANIZATION INDEXED ACCESS DYNAMIC RECORD KEY
KEYANTIGUO.
SELECT ARCHIVONUEVO ASSIGN TO RANDOM "NUEVO.DAT" ORGANIZATION INDEXED
ACCESS DYNAMIC RECORD KEY KEYNUEVO.
DATA DIVISION.
FILE SECTION.
FD ARCHIVOANTIGUO BLOCK 8 RECORDS RECORD 64 CHARACTERS
LABEL RECORD STANDARD.
01 REGANTIGUO.
02 KEYANTIGUO.
03 ANTFECHA PIC 9(6). (formato
inglés AAMMDD)
03 ANTPRODUCTO PIC 9(4).
02 ANTKILOS PIC 9(8).
02 ANTPRECIO PIC 9(6).
02 FILLER PIC X(40).
FD ARCHIVONUEVO BLOCK 8 RECORDS
RECORD 64 CHARACTERS
LABEL RECORD STANDARD.
01 REGNUEVO.
02 KEYNUEVO.
03 NUEFECHA PIC 9(8). (formato
inglés SSAAMMDD).
03 NUEPRODUCTO PIC 9(4).
02 NUEKILOS PIC 9(8).
02 NUEPRECIO PIC 9(6).
02 FILLER PIC X(38).
WORKING-STORAGE SECTION.
COPY "variables_para_las_rutinas".
PROCEDURE DIVISION.
INICIO.
OPEN OUTPUT ARCHIVONUEVO CLOSE
ARCHIVONUEVO.
OPEN INPUT ARCHIVOANTIGUO I-O ARCHIVONUEVO.
UNO.
READ ARCHIVOANTIGUO NEXT RECORD AT END GO FIN.
MOVE ANTPRODUCTO TO NUEPRODUCTO.
MOVE ANTKILOS TO NUEKILOS.
MOVE ANTPRECIO TO NUEPRECIO.
MOVE ANTFECHA TO FECA MOVE FDIA TO VARIABLE_PIC 99.
MOVE FANO TO FDIA MOVE VARIABLE_PIC 99 TO FANO.
PERFORM A2000 MOVE FEREV TO NUEFECHA.
WRITE REGNUEVO INVALID KEY DISPLAY "CAMBIO MAL".
GO UNO.
FIN.
CLOSE ARCHIVONUEVO ARCHIVOANTIGUO.
STOP RUN.
COPY "rutinas".
Como veis es muy simple, he tenido que
cambiar el orden del campo NUEFECHA , porque la rutina espera el campo fecha de 6 dígitos en formato
DDMMAA.
Una vez terminado el proceso cambiamos el nombre a NUEVO.DAT por ANTIGUO.DAT
y también la FD correspondiente para que el campo fecha tenga 8 dígitos.
Al comienzo os dije que todo esto se hiciera en un directorio aparte para poder probarlo bien antes de ponerlo definitivamente,
por lo que ésta conversión no será valida hasta que la hagamos sobre los datos reales.
2. Conversión de programas.
Una vez concluida la conversión de los archivos, nos disponemos a la de los programas,
ésta será mas compleja cuanto mas utilicemos los campos de fecha. Como queremos seguir
manteniendo en pantalla la fecha a 6 dígitos, cada vez que se introduzca una y la hayamos
validado la movemos a la variable FECA y le pasamos la rutina A2000 , con lo que obtendremos las dos variables
FESPA y FEREV , en castellano y en inglés para moverlas donde queramos.
Asimismo, cuando queramos mostrar una fecha de un archivo guardada en 8 dígitos la movemos a las variables FESPA o FEREV
dependiendo del formato y le pasamos la rutina DE8A6 o DE8A6R respectivamente, devolviendonos la fecha en 6 dígitos en la
variable FECA, siempre en formato castellano DDMMAA dispuesta para ser mostrada. Cuando hayamos convertido todos los
programas y verificados con los archivos, estaremos dispuestos para hacerlo con los datos
reales y poner fin al problema del año 2.000.
Hemos llegado al final, solo queda recordaros que todo esto es lo que yo he hecho y os aseguro que me
funciona, habrá mas soluciones y mejores seguro. Si teneis alguna duda os podeis poner en
contacto conmigo.
En mi empresa tenemos unos 260 programas y 85 archivos en los que existen campos fecha y la conversión
definitiva tardó 3 horas y media, en la que logicamente ningún usuario pudo trabajar, ya
veis que fue poco tiempo comparado con los calentamientos de cabeza que nos vamos a
quitar.
Como final os voy a poner algunos consejos muy importantes:
- Todo debe de estar probado, reprobado y vuelto a probar antes de hacerlo definitivamente.
- Introduce albaranes o facturas o lo que sea con fechas de 1999 y 2000 para comprobar que realmente funciona y que con las fechas
se puede operar bien.
- Vuelve a compilar todos los programas en los que estén incluidos los archivos con el problema de la fecha y no se utilice el campo
fecha, ya que la FD ha cambiado y por lo tanto la posición interna de los campos.
Si habeis llegado hasta aquí, FELICIDADES y MUCHAS GRACIAS, eso es que
os ha interesado y ese era el fin de ésta página.
|
|